Index: realpath.c
===================================================================
--- realpath.c	(revision 5811)
+++ realpath.c	(working copy)
@@ -597,20 +597,17 @@
 char *ccs_encode2(const char *str, int str_len)
 {
 	int i;
-	int len = 0;
+	int len;
 	const char *p = str;
 	char *cp;
 	char *cp0;
 	if (!p)
 		return NULL;
+	len = str_len;
 	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;
+		if (!(c > ' ' && c < 127 && c != '\\'))
+			len += 3;
 	}
 	len++;
 	/* Reserve space for appending "/". */
@@ -621,10 +618,7 @@
 	p = str;
 	for (i = 0; i < str_len; i++) {
 		const unsigned char c = p[i];
-		if (c == '\\') {
-			*cp++ = '\\';
-			*cp++ = '\\';
-		} else if (c > ' ' && c < 127) {
+		if (c > ' ' && c < 127 && c != '\\') {
 			*cp++ = c;
 		} else {
 			*cp++ = '\\';
@@ -674,9 +668,6 @@
 		}
 		c = *filename++;
 		switch (c) {
-		case '\\':  /* "\\" */
-			len += 2;
-			continue;
 		case '0':   /* "\ooo" */
 		case '1':
 		case '2':
Index: internal.h
===================================================================
--- internal.h	(revision 5811)
+++ internal.h	(working copy)
@@ -384,59 +384,30 @@
 
 /* Enumeration definition for internal use. */
 
-/* Index numbers for Access Controls. */
-enum ccs_acl_entry_type_index {
-	CCS_TYPE_EXECUTE_ACL,
-	CCS_TYPE_PATH_ACL,
-	CCS_TYPE_PATH2_ACL,
-	CCS_TYPE_PATH_NUMBER_ACL,
-	CCS_TYPE_MKDEV_ACL,
-	CCS_TYPE_MOUNT_ACL,
-#ifdef CONFIG_CCSECURITY_MISC
-	CCS_TYPE_ENV_ACL,
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-	CCS_TYPE_CAPABILITY_ACL,
-#endif
-#ifdef CONFIG_CCSECURITY_NETWORK
-	CCS_TYPE_INET_ACL,
-	CCS_TYPE_UNIX_ACL,
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-	CCS_TYPE_PTRACE_ACL,
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-	CCS_TYPE_AUTO_EXECUTE_HANDLER,
-	CCS_TYPE_DENIED_EXECUTE_HANDLER,
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-	CCS_TYPE_AUTO_TASK_ACL,
-	CCS_TYPE_MANUAL_TASK_ACL,
-#endif
-	CCS_TYPE_USE_GROUP_ACL,
-};
-
 /* Index numbers for "struct ccs_condition". */
 enum ccs_conditions_index {
-	CCS_TASK_UID,             /* current_uid()   */
-	CCS_TASK_EUID,            /* current_euid()  */
-	CCS_TASK_SUID,            /* current_suid()  */
-	CCS_TASK_FSUID,           /* current_fsuid() */
-	CCS_TASK_GID,             /* current_gid()   */
-	CCS_TASK_EGID,            /* current_egid()  */
-	CCS_TASK_SGID,            /* current_sgid()  */
-	CCS_TASK_FSGID,           /* current_fsgid() */
-	CCS_TASK_PID,             /* sys_getpid()   */
-	CCS_TASK_PPID,            /* sys_getppid()  */
+	CCS_SELF_UID,             /* current_uid()   */
+	CCS_SELF_EUID,            /* current_euid()  */
+	CCS_SELF_SUID,            /* current_suid()  */
+	CCS_SELF_FSUID,           /* current_fsuid() */
+	CCS_SELF_GID,             /* current_gid()   */
+	CCS_SELF_EGID,            /* current_egid()  */
+	CCS_SELF_SGID,            /* current_sgid()  */
+	CCS_SELF_FSGID,           /* current_fsgid() */
+	CCS_SELF_PID,             /* sys_getpid()   */
+	CCS_SELF_PPID,            /* sys_getppid()  */
+	CCS_TASK_TYPE,            /* ((u8) task->ccs_flags) &
+				     CCS_TASK_IS_EXECUTE_HANDLER */
+	CCS_SELF_DOMAIN,
 	CCS_EXEC_ARGC,            /* "struct linux_binprm *"->argc */
 	CCS_EXEC_ENVC,            /* "struct linux_binprm *"->envc */
-	CCS_TYPE_IS_SOCKET,       /* S_IFSOCK */
-	CCS_TYPE_IS_SYMLINK,      /* S_IFLNK */
-	CCS_TYPE_IS_FILE,         /* S_IFREG */
-	CCS_TYPE_IS_BLOCK_DEV,    /* S_IFBLK */
-	CCS_TYPE_IS_DIRECTORY,    /* S_IFDIR */
-	CCS_TYPE_IS_CHAR_DEV,     /* S_IFCHR */
-	CCS_TYPE_IS_FIFO,         /* S_IFIFO */
+	CCS_OBJ_IS_SOCKET,        /* S_IFSOCK */
+	CCS_OBJ_IS_SYMLINK,       /* S_IFLNK */
+	CCS_OBJ_IS_FILE,          /* S_IFREG */
+	CCS_OBJ_IS_BLOCK_DEV,     /* S_IFBLK */
+	CCS_OBJ_IS_DIRECTORY,     /* S_IFDIR */
+	CCS_OBJ_IS_CHAR_DEV,      /* S_IFCHR */
+	CCS_OBJ_IS_FIFO,          /* S_IFIFO */
 	CCS_MODE_SETUID,          /* S_ISUID */
 	CCS_MODE_SETGID,          /* S_ISGID */
 	CCS_MODE_STICKY,          /* S_ISVTX */
@@ -449,41 +420,46 @@
 	CCS_MODE_OTHERS_READ,     /* S_IROTH */
 	CCS_MODE_OTHERS_WRITE,    /* S_IWOTH */
 	CCS_MODE_OTHERS_EXECUTE,  /* S_IXOTH */
-	CCS_TASK_TYPE,            /* ((u8) task->ccs_flags) &
-				     CCS_TASK_IS_EXECUTE_HANDLER */
 	CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
-	CCS_EXEC_REALPATH,
-	CCS_PATH1_UID,
-	CCS_PATH1_GID,
-	CCS_PATH1_INO,
-	CCS_PATH1_MAJOR,
-	CCS_PATH1_MINOR,
-	CCS_PATH1_PERM,
-	CCS_PATH1_TYPE,
-	CCS_PATH1_DEV_MAJOR,
-	CCS_PATH1_DEV_MINOR,
-	CCS_PATH2_UID,
-	CCS_PATH2_GID,
-	CCS_PATH2_INO,
-	CCS_PATH2_MAJOR,
-	CCS_PATH2_MINOR,
-	CCS_PATH2_PERM,
-	CCS_PATH2_TYPE,
-	CCS_PATH2_DEV_MAJOR,
-	CCS_PATH2_DEV_MINOR,
-	CCS_PATH1_PARENT_UID,
-	CCS_PATH1_PARENT_GID,
-	CCS_PATH1_PARENT_INO,
-	CCS_PATH1_PARENT_PERM,
-	CCS_PATH2_PARENT_UID,
-	CCS_PATH2_PARENT_GID,
-	CCS_PATH2_PARENT_INO,
-	CCS_PATH2_PARENT_PERM,
+	CCS_HANDLER_PATH,
+	CCS_TRANSIT_DOMAIN,
+	//CCS_GRANT_LOG,
+	//CCS_REJECT_LOG,
 	CCS_MAX_CONDITION_KEYWORD,
-	CCS_NUMBER_UNION,
-	CCS_NAME_UNION,
+	CCS_COND_SARG0,
+	CCS_COND_SARG1,
+	CCS_COND_SARG2,
+	CCS_COND_NARG0,
+	CCS_COND_NARG1,
+	CCS_COND_NARG2,
+	CCS_COND_IPARG,
+	CCS_COND_DOMAIN,
+	CCS_IMM_GROUP,
+	CCS_IMM_NAME_ENTRY,
+	CCS_IMM_DOMAINNAME_ENTRY,
+	CCS_IMM_NUMBER_ENTRY1,
+	CCS_IMM_NUMBER_ENTRY2,
+	CCS_IMM_IPV4ADDR_ENTRY1,
+	CCS_IMM_IPV4ADDR_ENTRY2,
+	CCS_IMM_IPV6ADDR_ENTRY1,
+	CCS_IMM_IPV6ADDR_ENTRY2,
 	CCS_ARGV_ENTRY,
 	CCS_ENVP_ENTRY,
+	CCS_PATH_ATTRIBUTE_START = 192,
+	CCS_PATH_ATTRIBUTE_END = 255,
+} __packed;
+
+enum ccs_path_attribute_index {
+	CCS_PATH_ATTRIBUTE_UID,
+	CCS_PATH_ATTRIBUTE_GID,
+	CCS_PATH_ATTRIBUTE_INO,
+	CCS_PATH_ATTRIBUTE_TYPE,
+	CCS_PATH_ATTRIBUTE_MAJOR,
+	CCS_PATH_ATTRIBUTE_MINOR,
+	CCS_PATH_ATTRIBUTE_PERM,
+	CCS_PATH_ATTRIBUTE_DEV_MAJOR,
+	CCS_PATH_ATTRIBUTE_DEV_MINOR,
+	CCS_MAX_PATH_ATTRIBUTE,
 };
 
 /* Index numbers for audit type. */
@@ -522,6 +498,10 @@
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	CCS_MAC_CATEGORY_CAPABILITY,
 #endif
+#if defined(CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER) || defined(CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION)
+	CCS_MAC_CATEGORY_TASK,
+#endif
+	CCS_MAC_CATEGORY_NONE,
 	CCS_MAX_MAC_CATEGORY_INDEX
 };
 
@@ -600,7 +580,16 @@
 	CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
 	CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
 #endif
-	CCS_MAX_MAC_INDEX
+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
+	CCS_MAC_AUTO_EXECUTE_HANDLER,
+	CCS_MAC_DENIED_EXECUTE_HANDLER,
+#endif
+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
+	CCS_MAC_AUTO_TASK_TRANSITION,
+	CCS_MAC_MANUAL_TASK_TRANSITION,
+#endif
+	CCS_MAC_USE_GROUP,
+	CCS_MAX_MAC_INDEX,
 };
 
 /* Index numbers for /proc/ccs/stat interface. */
@@ -611,13 +600,6 @@
 	CCS_MAX_MEMORY_STAT
 };
 
-/* Index numbers for access controls with one pathname and three numbers. */
-enum ccs_mkdev_acl_index {
-	CCS_TYPE_MKBLOCK,
-	CCS_TYPE_MKCHAR,
-	CCS_MAX_MKDEV_OPERATION
-};
-
 /* Index numbers for operation mode. */
 enum ccs_mode_value {
 	CCS_CONFIG_DISABLED,
@@ -630,57 +612,6 @@
 	CCS_CONFIG_USE_DEFAULT     = 255,
 };
 
-/* Index numbers for socket operations. */
-enum ccs_network_acl_index {
-	CCS_NETWORK_BIND,    /* bind() operation. */
-	CCS_NETWORK_LISTEN,  /* listen() operation. */
-	CCS_NETWORK_CONNECT, /* connect() operation. */
-	CCS_NETWORK_ACCEPT,  /* accept() operation. */
-	CCS_NETWORK_SEND,    /* send() operation. */
-#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-	CCS_NETWORK_RECV,    /* recv() operation. */
-#endif
-	CCS_MAX_NETWORK_OPERATION
-};
-
-/* Index numbers for access controls with two pathnames. */
-enum ccs_path2_acl_index {
-	CCS_TYPE_LINK,
-	CCS_TYPE_RENAME,
-	CCS_TYPE_PIVOT_ROOT,
-	CCS_TYPE_SYMLINK,
-	CCS_MAX_PATH2_OPERATION
-};
-
-/* Index numbers for access controls with one pathname. */
-enum ccs_path_acl_index {
-	CCS_TYPE_READ,
-	CCS_TYPE_WRITE,
-	CCS_TYPE_APPEND,
-	CCS_TYPE_UNLINK,
-#ifdef CONFIG_CCSECURITY_FILE_GETATTR
-	CCS_TYPE_GETATTR,
-#endif
-	CCS_TYPE_RMDIR,
-	CCS_TYPE_TRUNCATE,
-	CCS_TYPE_CHROOT,
-	CCS_TYPE_UMOUNT,
-	CCS_MAX_PATH_OPERATION
-};
-
-/* Index numbers for access controls with one pathname and one number. */
-enum ccs_path_number_acl_index {
-	CCS_TYPE_CREATE,
-	CCS_TYPE_MKDIR,
-	CCS_TYPE_MKFIFO,
-	CCS_TYPE_MKSOCK,
-	CCS_TYPE_IOCTL,
-	CCS_TYPE_CHMOD,
-	CCS_TYPE_CHOWN,
-	CCS_TYPE_CHGRP,
-	CCS_MAX_PATH_NUMBER_OPERATION
-};
-
 /* Index numbers for stat(). */
 enum ccs_path_stat_index {
 	/* Do not change this order. */
@@ -845,43 +776,17 @@
 /* Common header for individual entries. */
 struct ccs_acl_info {
 	struct list_head list;
-	struct list_head domain_list; /* Used by inverse mode. */
+	struct list_head acl_info_list; /* Used by inverse mode. */
 	struct ccs_condition *cond; /* Maybe NULL. */
 	s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
-	u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
+	enum ccs_mac_index type;
 	u8 mode; /* Used by inverse mode. */
-	u16 perm;
 } __packed;
 
-/* Structure for holding a word. */
-struct ccs_name_union {
-	/* Either @filename or @group is NULL. */
-	const struct ccs_path_info *filename;
-	struct ccs_group *group;
-	bool is_not;
-};
-
-/* Structure for holding a number. */
-struct ccs_number_union {
-	unsigned long values[2];
-	struct ccs_group *group; /* Maybe NULL. */
-	/* One of values in "enum ccs_value_type". */
-	u8 value_type[2];
-	bool is_not;
-};
-
-/* Structure for holding an IP address. */
-struct ccs_ipaddr_union {
-	struct in6_addr ip[2]; /* Big endian. */
-	struct ccs_group *group; /* Pointer to address group. */
-	bool is_ipv6; /* Valid only if @group == NULL. */
-	bool is_not;
-};
-
 /* Structure for "path_group"/"number_group"/"address_group" directive. */
 struct ccs_group {
 	struct ccs_shared_acl_head head;
-	/* Name of group (without leading "\\=" or "\\!"). */
+	/* Name of group (without leading "@"). */
 	const struct ccs_path_info *group_name;
 	/*
 	 * List of "struct ccs_path_group" or "struct ccs_number_group" or
@@ -899,15 +804,16 @@
 /* Structure for "number_group" directive. */
 struct ccs_number_group {
 	struct ccs_acl_head head;
-	struct ccs_number_union number;
+	unsigned long value[2];
+	u8 radix;
 };
 
 /* Structure for "address_group" directive. */
 struct ccs_address_group {
 	struct ccs_acl_head head;
 	/* Structure for holding an IP address. */
-	struct ccs_ipaddr_union address;
-	bool is_not;
+	struct in6_addr ip[2]; /* Big endian. */
+	bool is_ipv6;
 };
 
 /* Subset of "struct stat". Used by conditional ACL and audit logs. */
@@ -944,44 +850,28 @@
 };
 
 /* Structure for entries which follows "struct ccs_condition". */
-struct ccs_condition_element {
-	/*
-	 * Left hand operand. A "struct ccs_argv" for CCS_ARGV_ENTRY, a
-	 * "struct ccs_envp" for CCS_ENVP_ENTRY is attached to the tail
-	 * of the array of this struct.
-	 */
-	u8 left;
-	/*
-	 * Right hand operand. A "struct ccs_number_union" for
-	 * CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_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;
+union ccs_condition_element {
+	struct {
+		enum ccs_conditions_index left;
+		enum ccs_conditions_index right;
+		bool equals;
+		u8 radix;
+	};
+	struct ccs_group *group;
+	const struct ccs_path_info *path;
+	u32 ip; /* Repeat 4 times if IPv6 address. */
+	unsigned long value;
+	u8 grant_log; /* One of values in "enum ccs_grant_log". */
 };
 
 /* Structure for optional arguments. */
 struct ccs_condition {
 	struct ccs_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 ccs_number_union values". */
-	u16 names_count; /* Number of "struct ccs_name_union names". */
-	u16 argc; /* Number of "struct ccs_argv". */
-	u16 envc; /* Number of "struct ccs_envp". */
-	u8 grant_log; /* One of values in "enum ccs_grant_log". */
-	/*
-	 * struct ccs_condition_element condition[condc];
-	 * struct ccs_number_union values[numbers_count];
-	 * struct ccs_name_union names[names_count];
-	 * struct ccs_argv argv[argc];
-	 * struct ccs_envp envp[envc];
-	 */
+	/* union ccs_condition_element condition[]; */
 };
 
 struct ccs_execve;
-struct ccs_policy_namespace;
 
 /* Structure for request info. */
 struct ccs_request_info {
@@ -995,92 +885,28 @@
 	 * NULL if not dealing do_execve().
 	 */
 	struct ccs_execve *ee;
-	/* For holding parameters. Pointers in this union are not NULL. */
-	union {
-		struct {
-			const struct ccs_path_info *program;
-		} execute;
-		struct {
-			const struct ccs_path_info *filename;
-			/* One of values in "enum ccs_path_acl_index". */
-			u8 operation;
-		} path;
-		struct {
-			const struct ccs_path_info *filename1;
-			const struct ccs_path_info *filename2;
-			/* One of values in "enum ccs_path2_acl_index". */
-			u8 operation;
-		} path2;
-		struct {
-			const struct ccs_path_info *filename;
-			unsigned int mode;
-			unsigned int major;
-			unsigned int minor;
-			/* One of values in "enum ccs_mkdev_acl_index". */
-			u8 operation;
-		} mkdev;
-		struct {
-			const struct ccs_path_info *filename;
-			unsigned long number;
-			/*
-			 * One of values in "enum ccs_path_number_acl_index".
-			 */
-			u8 operation;
-		} path_number;
+	/* For holding parameters. */
+	struct ccs_request_param {
+		const struct ccs_path_info *s[3];
+		unsigned long i[3];
 #ifdef CONFIG_CCSECURITY_NETWORK
-		struct {
-			const u32 *address; /* Big endian. */
-			u16 port; /* Host endian. */
-			/* One of values smaller than CCS_SOCK_MAX. */
-			u8 protocol;
-			/* One of values in "enum ccs_network_acl_index". */
-			u8 operation;
-			bool is_ipv6;
-		} inet_network;
-		struct {
-			const struct ccs_path_info *address;
-			/* One of values smaller than CCS_SOCK_MAX. */
-			u8 protocol;
-			/* One of values in "enum ccs_network_acl_index". */
-			u8 operation;
-		} unix_network;
+		const u8 *ip; /* Big endian. */
+		bool is_ipv6;
 #endif
-#ifdef CONFIG_CCSECURITY_MISC
-		struct {
-			const struct ccs_path_info *name;
-		} environ;
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-		struct {
-			/* One of values in "enum ccs_capability_acl_index". */
-			u8 operation;
-		} capability;
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-		struct {
-			const char *domainname;
-			unsigned long request;
-		} ptrace;
-#endif
-		struct {
-			const struct ccs_path_info *type;
-			const struct ccs_path_info *dir;
-			const struct ccs_path_info *dev;
-			unsigned long flags;
-			int need_dev;
-		} mount;
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-		struct {
-			const struct ccs_path_info *domainname;
-		} task;
-#endif
 	} param;
 	/*
 	 * Matching "struct ccs_acl_info" is copied if access request was
 	 * granted.
 	 */
 	struct ccs_acl_info *matched_acl;
-	u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */
+	/* handler and domain transition is copied. */
+	const struct ccs_path_info *handler_path;
+	const struct ccs_path_info *transition;
+	/*
+	 * For holding operation index used for this request.
+	 * One of values in "enum ccs_mac_index".
+	 */
+	enum ccs_mac_index type;
 	bool granted; /* True if granted, false otherwise. */
 	/* True if rejected by inverse mode match, false otherwise. */
 	bool inversed;
@@ -1103,11 +929,6 @@
 	 * CCS_CONFIG_PERMISSIVE, CCS_CONFIG_ENFORCING.
 	 */
 	u8 mode;
-	/*
-	 * For holding operation index used for this request.
-	 * One of values in "enum ccs_mac_index".
-	 */
-	u8 type;
 };
 
 /* Structure for holding a token. */
@@ -1142,14 +963,11 @@
 	struct list_head acl_info_list;
 	/* Name of this domain. Never NULL.          */
 	const struct ccs_path_info *domainname;
-	/* Namespace for this domain. Never NULL. */
-	struct ccs_policy_namespace *ns;
 	/* Default domain transition. Never NULL. */
 	const struct ccs_path_info *default_transition;
 	u8 profile;        /* Profile number to use. */
 	bool quota_exceeded;
 	s8 is_deleted;     /* Delete flag.           */
-	struct ccs_condition *cond; /* Used by inverse mode. */
 };
 
 /* Structure for policy manager. */
@@ -1160,148 +978,10 @@
 	const struct ccs_path_info *manager;
 };
 
-/* Structure for argv[]. */
-struct ccs_argv {
-	unsigned long index;
-	const struct ccs_path_info *value;
-	bool is_not;
-};
-
-/* Structure for envp[]. */
-struct ccs_envp {
-	const struct ccs_path_info *name;
-	const struct ccs_path_info *value;
-	bool is_not;
-};
-
-/*
- * Structure for "task auto_execute_handler" and "task denied_execute_handler"
- * directive.
- *
- * If "task auto_execute_handler" directive exists and the current process is
- * not an execute handler, all execve() requests are replaced by execve()
- * requests of a program specified by "task auto_execute_handler" directive.
- * If the current process is an execute handler, "task auto_execute_handler"
- * and "task denied_execute_handler" directives are ignored.
- * The program specified by "task execute_handler" validates execve()
- * parameters and executes the original execve() requests if appropriate.
- *
- * "task denied_execute_handler" directive is used only when execve() request
- * was rejected in enforcing mode (i.e. CONFIG::file::execute={ mode=enforcing
- * }). The program specified by "task denied_execute_handler" does whatever it
- * wants to do (e.g. silently terminate, change firewall settings, redirect the
- * user to honey pot etc.).
- */
-struct ccs_handler_acl {
-	struct ccs_acl_info head;       /* type = CCS_TYPE_*_EXECUTE_HANDLER */
-	const struct ccs_path_info *handler; /* Pointer to single pathname.  */
-	const struct ccs_path_info *transit; /* Maybe NULL. */
-};
-
-/*
- * Structure for "task auto_domain_transition" and
- * "task manual_domain_transition" directive.
- */
-struct ccs_task_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_*_TASK_ACL */
-	/* Pointer to domainname. */
-	const struct ccs_path_info *domainname;
-};
-
-/* Structure for "file execute" directive. */
-struct ccs_execute_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_EXECUTE_ACL */
-	struct ccs_name_union program;
-	const struct ccs_path_info *transit; /* Maybe NULL. */
-};
-
-/*
- * Structure for "file read", "file write", "file append", "file unlink",
- * "file getattr", "file rmdir", "file truncate", "file chroot" and
- * "file unmount" directive.
- */
-struct ccs_path_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
-	struct ccs_name_union name;
-};
-
-/*
- * Structure for "file rename", "file link", "file pivot_root" and
- * "file symlink" directive.
- */
-struct ccs_path2_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
-	struct ccs_name_union name1;
-	struct ccs_name_union name2;
-};
-
-/*
- * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
- * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
- */
-struct ccs_path_number_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
-	struct ccs_name_union name;
-	struct ccs_number_union number;
-};
-
-/* Structure for "file mkblock" and "file mkchar" directive. */
-struct ccs_mkdev_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */
-	struct ccs_name_union name;
-	struct ccs_number_union mode;
-	struct ccs_number_union major;
-	struct ccs_number_union minor;
-};
-
-/* Structure for "file mount" directive. */
-struct ccs_mount_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */
-	struct ccs_name_union dev_name;
-	struct ccs_name_union dir_name;
-	struct ccs_name_union fs_type;
-	struct ccs_number_union flags;
-};
-
-/* Structure for "misc env" directive in domain policy. */
-struct ccs_env_acl {
-	struct ccs_acl_info head;  /* type = CCS_TYPE_ENV_ACL  */
-	struct ccs_name_union env; /* environment variable */
-};
-
-/* Structure for "capability" directive. */
-struct ccs_capability_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */
-	u8 operation; /* One of values in "enum ccs_capability_acl_index". */
-};
-
-/* Structure for "ipc ptrace" directive. */
-struct ccs_ptrace_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_PTRACE_ACL */
-	struct ccs_number_union request;
-	const struct ccs_path_info *domainname;
-};
-
-/* Structure for "network inet" directive. */
-struct ccs_inet_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */
-	u8 protocol;
-	struct ccs_ipaddr_union address;
-	struct ccs_number_union port;
-};
-
-/* Structure for "network unix" directive. */
-struct ccs_unix_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */
-	u8 protocol;
-	struct ccs_name_union name;
-};
-
 /* Structure for "use_group" directive. */
 struct ccs_use_group_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_USE_GROUP_ACL */
+	struct ccs_acl_info head; /* type = CCS_MAC_USE_GROUP */
 	struct ccs_group *group;
-	bool is_not;
 };
 
 /* Structure for holding string data. */
@@ -1315,23 +995,9 @@
 struct ccs_acl_param {
 	char *data; /* Unprocessed data. */
 	struct list_head *list; /* List to add or remove. */
-	struct ccs_policy_namespace *ns; /* Namespace to use. */
 	bool is_delete; /* True if it is a delete request. */
 	union ccs_acl_union {
 		struct ccs_acl_info acl_info;
-		struct ccs_handler_acl handler_acl;
-		struct ccs_task_acl task_acl;
-		struct ccs_execute_acl execute_acl;
-		struct ccs_path_acl path_acl;
-		struct ccs_path2_acl path2_acl;
-		struct ccs_path_number_acl path_number_acl;
-		struct ccs_mkdev_acl mkdev_acl;
-		struct ccs_mount_acl mount_acl;
-		struct ccs_env_acl env_acl;
-		struct ccs_capability_acl capability_acl;
-		struct ccs_ptrace_acl ptrace_acl;
-		struct ccs_inet_acl inet_acl;
-		struct ccs_unix_acl unix_acl;
 		struct ccs_use_group_acl use_group_acl;
 		/**/
 		struct ccs_acl_head acl_head;
@@ -1354,24 +1020,22 @@
 		struct list_head *domain;
 		struct list_head *group;
 		struct list_head *acl;
+		const union ccs_condition_element *cond;
 		const struct ccs_path_info *acl_group_name;
 		size_t avail;
 		unsigned int step;
 		unsigned int query_index;
 		u16 index;
-		u16 cond_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;
 		bool print_default_transition;
 		const char *w[CCS_MAX_IO_READ_QUEUE];
 	} r;
 	struct {
-		struct ccs_policy_namespace *ns;
 		struct ccs_domain_info *domain;
 		struct ccs_acl_info *acl; /* Used by inverse mode. */
 		size_t avail;
@@ -1411,22 +1075,6 @@
 	u8 sec;
 };
 
-/* Structure for policy namespace. */
-struct ccs_policy_namespace {
-	/* Profile table. Memory is allocated as needed. */
-	struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
-	/* List of "struct ccs_group". */
-	struct list_head group_list[CCS_MAX_GROUP];
-	/* List of default transition pattern. */
-	struct list_head default_transition_list;
-	/* List for connecting to ccs_namespace_list list. */
-	struct list_head namespace_list;
-	/* Profile version. Currently only 20100903 is defined. */
-	unsigned int profile_version;
-	/* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
-	const char *name;
-};
-
 /* Prototype definition for "struct ccsecurity_operations". */
 
 void __init ccs_permission_init(void);
@@ -1459,18 +1107,13 @@
 /* Variable definition for internal use. */
 
 extern bool ccs_policy_loaded;
-extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX];
-extern const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION];
-extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION];
-extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION];
-extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION];
 extern struct ccs_domain_info ccs_kernel_domain;
-extern struct ccs_group ccs_group_any;
 extern struct list_head ccs_condition_list;
+extern struct list_head ccs_default_transition_list;
 extern struct list_head ccs_domain_list;
+extern struct list_head ccs_group_list[CCS_MAX_GROUP];
 extern struct list_head ccs_inversed_acl_list;
 extern struct list_head ccs_name_list[CCS_MAX_HASH];
-extern struct list_head ccs_namespace_list;
 extern struct list_head ccs_manager_list;
 extern struct mutex ccs_policy_lock;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
@@ -1957,14 +1600,4 @@
 
 #endif
 
-/**
- * ccs_current_namespace - Get "struct ccs_policy_namespace" for current thread.
- *
- * Returns pointer to "struct ccs_policy_namespace" for current thread.
- */
-static inline struct ccs_policy_namespace *ccs_current_namespace(void)
-{
-	return ccs_current_domain()->ns;
-}
-
 #endif
Index: policy_io.c
===================================================================
--- policy_io.c	(revision 5811)
+++ policy_io.c	(working copy)
@@ -99,6 +99,15 @@
 	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY,
 	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = CCS_MAC_CATEGORY_CAPABILITY,
 #endif
+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
+	[CCS_MAC_AUTO_EXECUTE_HANDLER]   = CCS_MAC_CATEGORY_TASK,
+	[CCS_MAC_DENIED_EXECUTE_HANDLER] = CCS_MAC_CATEGORY_TASK,
+#endif
+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
+	[CCS_MAC_AUTO_TASK_TRANSITION]   = CCS_MAC_CATEGORY_TASK,
+	[CCS_MAC_MANUAL_TASK_TRANSITION] = CCS_MAC_CATEGORY_TASK,
+#endif
+	[CCS_MAC_USE_GROUP]              = CCS_MAC_CATEGORY_NONE,
 };
 
 /* String table for operation mode. */
@@ -190,6 +199,18 @@
 	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
 	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = "SYS_KEXEC_LOAD",
 #endif
+	/* No corresponding profile line. */
+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
+	[CCS_MAC_AUTO_EXECUTE_HANDLER]   = "auto_execute_handler",
+	[CCS_MAC_DENIED_EXECUTE_HANDLER] = "denied_execute_handler",
+#endif
+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
+	[CCS_MAC_AUTO_TASK_TRANSITION]   = "auto_domain_transition",
+	[CCS_MAC_MANUAL_TASK_TRANSITION] = "manual_domain_transition",
+#endif
+	[CCS_MAC_USE_GROUP] = "",
+	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_TASK]       = "task",
+	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NONE]       = "",
 	/* CONFIG group */
 	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE]       = "file",
 #ifdef CONFIG_CCSECURITY_NETWORK
@@ -206,32 +227,6 @@
 #endif
 };
 
-#ifdef CONFIG_CCSECURITY_NETWORK
-
-/* String table for socket's operation. */
-static const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION] = {
-	[CCS_NETWORK_BIND]    = "bind",
-	[CCS_NETWORK_LISTEN]  = "listen",
-	[CCS_NETWORK_CONNECT] = "connect",
-	[CCS_NETWORK_ACCEPT]  = "accept",
-	[CCS_NETWORK_SEND]    = "send",
-#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-	[CCS_NETWORK_RECV]    = "recv",
-#endif
-};
-
-/* String table for socket's protocols. */
-static const char * const ccs_proto_keyword[CCS_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. */
-};
-
-#endif
-
 /* String table for categories. */
 static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = {
 	[CCS_MAC_CATEGORY_FILE]       = "file",
@@ -247,29 +242,33 @@
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	[CCS_MAC_CATEGORY_CAPABILITY] = "capability",
 #endif
+	[CCS_MAC_CATEGORY_TASK]       = "task",
+	[CCS_MAC_CATEGORY_NONE]       = "",
 };
 
 /* String table for conditions. */
-static const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = {
-	[CCS_TASK_UID]             = "task.uid",
-	[CCS_TASK_EUID]            = "task.euid",
-	[CCS_TASK_SUID]            = "task.suid",
-	[CCS_TASK_FSUID]           = "task.fsuid",
-	[CCS_TASK_GID]             = "task.gid",
-	[CCS_TASK_EGID]            = "task.egid",
-	[CCS_TASK_SGID]            = "task.sgid",
-	[CCS_TASK_FSGID]           = "task.fsgid",
-	[CCS_TASK_PID]             = "task.pid",
-	[CCS_TASK_PPID]            = "task.ppid",
-	[CCS_EXEC_ARGC]            = "exec.argc",
-	[CCS_EXEC_ENVC]            = "exec.envc",
-	[CCS_TYPE_IS_SOCKET]       = "socket",
-	[CCS_TYPE_IS_SYMLINK]      = "symlink",
-	[CCS_TYPE_IS_FILE]         = "file",
-	[CCS_TYPE_IS_BLOCK_DEV]    = "block",
-	[CCS_TYPE_IS_DIRECTORY]    = "directory",
-	[CCS_TYPE_IS_CHAR_DEV]     = "char",
-	[CCS_TYPE_IS_FIFO]         = "fifo",
+static const char *const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = {
+	[CCS_SELF_UID]             = "uid",
+	[CCS_SELF_EUID]            = "euid",
+	[CCS_SELF_SUID]            = "suid",
+	[CCS_SELF_FSUID]           = "fsuid",
+	[CCS_SELF_GID]             = "gid",
+	[CCS_SELF_EGID]            = "egid",
+	[CCS_SELF_SGID]            = "sgid",
+	[CCS_SELF_FSGID]           = "fsgid",
+	[CCS_SELF_PID]             = "pid",
+	[CCS_SELF_PPID]            = "ppid",
+	[CCS_TASK_TYPE]            = "type",
+	[CCS_SELF_DOMAIN]          = "domain",
+	[CCS_EXEC_ARGC]            = "argc",
+	[CCS_EXEC_ENVC]            = "envc",
+	[CCS_OBJ_IS_SOCKET]        = "socket",
+	[CCS_OBJ_IS_SYMLINK]       = "symlink",
+	[CCS_OBJ_IS_FILE]          = "file",
+	[CCS_OBJ_IS_BLOCK_DEV]     = "block",
+	[CCS_OBJ_IS_DIRECTORY]     = "directory",
+	[CCS_OBJ_IS_CHAR_DEV]      = "char",
+	[CCS_OBJ_IS_FIFO]          = "fifo",
 	[CCS_MODE_SETUID]          = "setuid",
 	[CCS_MODE_SETGID]          = "setgid",
 	[CCS_MODE_STICKY]          = "sticky",
@@ -282,35 +281,11 @@
 	[CCS_MODE_OTHERS_READ]     = "others_read",
 	[CCS_MODE_OTHERS_WRITE]    = "others_write",
 	[CCS_MODE_OTHERS_EXECUTE]  = "others_execute",
-	[CCS_TASK_TYPE]            = "task.type",
 	[CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
-	[CCS_EXEC_REALPATH]        = "exec.realpath",
-	[CCS_PATH1_UID]            = "path1.uid",
-	[CCS_PATH1_GID]            = "path1.gid",
-	[CCS_PATH1_INO]            = "path1.ino",
-	[CCS_PATH1_MAJOR]          = "path1.major",
-	[CCS_PATH1_MINOR]          = "path1.minor",
-	[CCS_PATH1_PERM]           = "path1.perm",
-	[CCS_PATH1_TYPE]           = "path1.type",
-	[CCS_PATH1_DEV_MAJOR]      = "path1.dev_major",
-	[CCS_PATH1_DEV_MINOR]      = "path1.dev_minor",
-	[CCS_PATH2_UID]            = "path2.uid",
-	[CCS_PATH2_GID]            = "path2.gid",
-	[CCS_PATH2_INO]            = "path2.ino",
-	[CCS_PATH2_MAJOR]          = "path2.major",
-	[CCS_PATH2_MINOR]          = "path2.minor",
-	[CCS_PATH2_PERM]           = "path2.perm",
-	[CCS_PATH2_TYPE]           = "path2.type",
-	[CCS_PATH2_DEV_MAJOR]      = "path2.dev_major",
-	[CCS_PATH2_DEV_MINOR]      = "path2.dev_minor",
-	[CCS_PATH1_PARENT_UID]     = "path1.parent.uid",
-	[CCS_PATH1_PARENT_GID]     = "path1.parent.gid",
-	[CCS_PATH1_PARENT_INO]     = "path1.parent.ino",
-	[CCS_PATH1_PARENT_PERM]    = "path1.parent.perm",
-	[CCS_PATH2_PARENT_UID]     = "path2.parent.uid",
-	[CCS_PATH2_PARENT_GID]     = "path2.parent.gid",
-	[CCS_PATH2_PARENT_INO]     = "path2.parent.ino",
-	[CCS_PATH2_PARENT_PERM]    = "path2.parent.perm",
+	[CCS_HANDLER_PATH]         = "handler",
+	[CCS_TRANSIT_DOMAIN]       = "transition",
+	//[CCS_GRANT_LOG]          = "grant_log",
+	//[CCS_REJECT_LOG]         = "reject_log",
 };
 
 /* String table for PREFERENCE keyword. */
@@ -381,37 +356,21 @@
 static bool ccs_correct_path(const char *filename);
 static bool ccs_correct_word(const char *string);
 static bool ccs_correct_word2(const char *string, size_t len);
-static bool ccs_domain_def(const unsigned char *buffer);
 static bool ccs_domain_quota_ok(struct ccs_request_info *r);
 static bool ccs_flush(struct ccs_io_buffer *head);
 static bool ccs_get_audit(const struct ccs_request_info *r);
-static bool ccs_has_more_namespace(struct ccs_io_buffer *head);
 static bool ccs_manager(void);
-static bool ccs_namespace_jump(const char *domainname);
-static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv);
-static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp);
-static bool ccs_parse_name_union(struct ccs_acl_param *param,
-				 struct ccs_name_union *ptr);
-static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
-					struct ccs_name_union *ptr);
-static bool ccs_parse_number_union(struct ccs_acl_param *param,
-				   struct ccs_number_union *ptr);
-static bool ccs_permstr(const char *string, const char *keyword);
 static bool ccs_print_condition(struct ccs_io_buffer *head,
+				const enum ccs_mac_index type,
 				const struct ccs_condition *cond);
 static bool ccs_print_entry(struct ccs_io_buffer *head,
 			    const struct ccs_acl_info *acl);
-static bool ccs_print_group(struct ccs_io_buffer *head, const bool is_not,
-			    const struct ccs_group *group);
 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list);
 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx);
-static bool ccs_same_condition(const struct ccs_condition *a,
-			       const struct ccs_condition *b);
 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data);
 static bool ccs_set_lf(struct ccs_io_buffer *head);
 static bool ccs_str_starts(char **src, const char *find);
-static char *ccs_get_transit_preference(struct ccs_acl_param *param,
-					struct ccs_execute_acl *e);
+struct ccs_execute_acl;
 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt,
 			  va_list args);
 static char *ccs_print_bprm(struct linux_binprm *bprm,
@@ -419,8 +378,6 @@
 static char *ccs_print_header(struct ccs_request_info *r);
 static char *ccs_read_token(struct ccs_acl_param *param);
 static const char *ccs_yesno(const unsigned int value);
-static const struct ccs_path_info *ccs_get_domainname
-(struct ccs_acl_param *param);
 static const struct ccs_path_info *ccs_get_dqword(char *start);
 static int __init ccs_init_module(void);
 static int ccs_delete_domain(char *domainname);
@@ -433,26 +390,22 @@
 			struct ccs_profile *profile);
 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
 	__printf(2, 3);
-static int ccs_update_acl(const int size, struct ccs_acl_param *param);
 static int ccs_update_inverse_list(struct ccs_acl_info *new_entry,
 				   const int size,
 				   struct ccs_acl_param *param);
 static int ccs_update_manager_entry(const char *manager, const bool is_delete);
 static int ccs_update_policy(const int size, struct ccs_acl_param *param);
-static int ccs_write_acl(struct ccs_policy_namespace *ns,
-			 struct list_head *list, char *data,
+static int ccs_write_acl(struct list_head *list, char *data,
 			 const bool is_delete);
 static int ccs_write_acl_policy(struct ccs_io_buffer *head);
 static int ccs_write_answer(struct ccs_io_buffer *head);
 static int ccs_write_domain(struct ccs_io_buffer *head);
 static int ccs_write_exception(struct ccs_io_buffer *head);
-static int ccs_write_file(struct ccs_acl_param *param);
 static int ccs_write_group(struct ccs_acl_param *param, const u8 type);
 static int ccs_write_manager(struct ccs_io_buffer *head);
 static int ccs_write_pid(struct ccs_io_buffer *head);
 static int ccs_write_profile(struct ccs_io_buffer *head);
 static int ccs_write_stat(struct ccs_io_buffer *head);
-static int ccs_write_task(struct ccs_acl_param *param);
 static int ccs_write_transition_control(struct ccs_acl_param *param);
 static int ccs_write_use_group_acl(struct ccs_acl_param *param);
 static s8 ccs_find_yesno(const char *string, const char *find);
@@ -462,22 +415,14 @@
 			     loff_t *ppos);
 static ssize_t ccs_write(struct file *file, const char __user *buf,
 			 size_t count, loff_t *ppos);
-static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry);
 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param);
 static struct ccs_domain_info *ccs_find_domain(const char *domainname);
 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial);
 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
 				       const u8 idx);
-static struct ccs_policy_namespace *ccs_assign_namespace
-(const char *domainname);
-static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
-						       const unsigned int len);
-static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
-					      const unsigned int profile);
+static struct ccs_profile *ccs_assign_profile(const unsigned int profile);
 static struct ccs_profile *ccs_profile(const u8 profile);
-static u8 ccs_condition_type(const char *word);
 static u8 ccs_get_config(const u8 profile, const u8 index);
-static u8 ccs_group_type(char **src);
 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3);
 static u8 ccs_parse_ulong(unsigned long *result, char **str);
 static unsigned int ccs_poll(struct file *file, poll_table *wait);
@@ -493,20 +438,10 @@
 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...);
 static void ccs_check_profile(void);
 static void ccs_convert_time(time_t time, struct ccs_time *stamp);
-static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns);
 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
 	__printf(2, 3);
 static void ccs_normalize_line(unsigned char *buffer);
 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config);
-static void ccs_print_name_union(struct ccs_io_buffer *head,
-				 const struct ccs_name_union *ptr);
-static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
-					const struct ccs_name_union *ptr);
-static void ccs_print_namespace(struct ccs_io_buffer *head);
-static void ccs_print_number_union(struct ccs_io_buffer *head,
-				   const struct ccs_number_union *ptr);
-static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
-					   const struct ccs_number_union *ptr);
 static void ccs_read_domain(struct ccs_io_buffer *head);
 static void ccs_read_exception(struct ccs_io_buffer *head);
 static void ccs_read_inverse_policy(struct ccs_io_buffer *head);
@@ -518,8 +453,6 @@
 static void ccs_read_stat(struct ccs_io_buffer *head);
 static void ccs_read_version(struct ccs_io_buffer *head);
 static void ccs_set_group(struct ccs_io_buffer *head, const char *category);
-static void ccs_set_namespace_cursor(struct ccs_io_buffer *head);
-static void ccs_set_slash(struct ccs_io_buffer *head);
 static void ccs_set_space(struct ccs_io_buffer *head);
 static void ccs_set_string(struct ccs_io_buffer *head, const char *string);
 static void ccs_set_uint(unsigned int *i, const char *string,
@@ -532,30 +465,14 @@
 
 
 #ifdef CONFIG_CCSECURITY_NETWORK
-static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
-				   struct ccs_ipaddr_union *ptr);
 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
-			  const u32 *ip);
+			  const u8 *ip);
 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len,
 			  const struct in6_addr *ip);
-static int ccs_write_inet_network(struct ccs_acl_param *param);
-static int ccs_write_unix_network(struct ccs_acl_param *param);
 static void ccs_print_ip(char *buf, const unsigned int size,
-			 const struct ccs_ipaddr_union *ptr);
+			 bool is_ipv6, const struct in6_addr ip[2]);
 #endif
 
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-static int ccs_write_capability(struct ccs_acl_param *param);
-#endif
-
-#ifdef CONFIG_CCSECURITY_MISC
-static int ccs_write_misc(struct ccs_acl_param *param);
-#endif
-
-#ifdef CONFIG_CCSECURITY_IPC
-static int ccs_write_ipc(struct ccs_acl_param *param);
-#endif
-
 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
 static ssize_t ccs_write_self(struct file *file, const char __user *buf,
 			      size_t count, loff_t *ppos);
@@ -1088,18 +1005,18 @@
  *
  * @buffer:     Buffer to write to.
  * @buffer_len: Size of @buffer.
- * @ip:         Pointer to "u32 in network byte order".
+ * @ip:         Pointer to "u8" in network byte order.
  *
  * Returns written length.
  */
 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len,
-			  const u32 *ip)
+			  const u8 *ip)
 {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
 	return snprintf(buffer, buffer_len, "%pI4", ip);
 #else
 	char addr[sizeof("255.255.255.255")];
-	ip4_string(addr, (const u8 *) ip);
+	ip4_string(addr, ip);
 	return snprintf(buffer, buffer_len, "%s", addr);
 #endif
 }
@@ -1128,32 +1045,222 @@
 /**
  * ccs_print_ip - Print an IP address.
  *
- * @buf:  Buffer to write to.
- * @size: Size of @buf.
- * @ptr:  Pointer to "struct ipaddr_union".
+ * @buf:     Buffer to write to.
+ * @size:    Size of @buf.
+ * @is_ipv6: True if IPv6 address, false otherwise.
+ * @ip:      Pointer to "struct in6_addr".
  *
  * Returns nothing.
  */
 static void ccs_print_ip(char *buf, const unsigned int size,
-			 const struct ccs_ipaddr_union *ptr)
+			 bool is_ipv6, const struct in6_addr ip[2])
 {
 	int len;
-	if (ptr->is_ipv6)
-		len = ccs_print_ipv6(buf, size, &ptr->ip[0]);
+	if (is_ipv6)
+		len = ccs_print_ipv6(buf, size, &ip[0]);
 	else
-		len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]);
-	if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2)
+		len = ccs_print_ipv4(buf, size, ip[0].s6_addr);
+	if (!memcmp(&ip[0], &ip[1], 16) || len >= size / 2)
 		return;
 	buf[len++] = '-';
-	if (ptr->is_ipv6)
-		ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]);
+	if (is_ipv6)
+		ccs_print_ipv6(buf + len, size - len, &ip[1]);
 	else
-		ccs_print_ipv4(buf + len, size - len,
-			       &ptr->ip[1].s6_addr32[0]);
+		ccs_print_ipv4(buf + len, size - len, ip[1].s6_addr);
 }
 
 #endif
 
+/**
+ * ccs_get_sarg - Get attribute name of CCS_SARG argument.
+ *
+ * @type:  One of values in "enum ccs_mac_index".
+ * @index: Index to return.
+ *
+ * Returns attribute name.
+ */
+static const char *ccs_get_sarg(const enum ccs_mac_index type, const u8 index)
+{
+	switch (type) {
+        case CCS_MAC_FILE_LINK:
+        case CCS_MAC_FILE_RENAME:
+		if (index == 0)
+			return "old_path";
+		if (index == 1)
+			return "new_path";
+		break;
+	case CCS_MAC_FILE_MOUNT:
+		if (index == 0)
+			return "source";
+		if (index == 1)
+			return "target";
+		if (index == 2)
+			return "fstype";
+		break;
+	case CCS_MAC_FILE_PIVOT_ROOT:
+		if (index == 0)
+			return "new_root";
+		if (index == 1)
+			return "put_old";
+		break;
+	case CCS_MAC_FILE_EXECUTE:
+		if (index == 0)
+			return "path";
+		if (index == 1)
+			return "exec";
+		break;
+	case CCS_MAC_FILE_SYMLINK:
+		if (index == 0)
+			return "path";
+		if (index == 1)
+			return "target";
+		break;
+	case CCS_MAC_FILE_READ:
+	case CCS_MAC_FILE_WRITE:
+	case CCS_MAC_FILE_APPEND:
+	case CCS_MAC_FILE_UNLINK:
+	case CCS_MAC_FILE_GETATTR:
+	case CCS_MAC_FILE_RMDIR:
+	case CCS_MAC_FILE_TRUNCATE:
+	case CCS_MAC_FILE_CHROOT:
+	case CCS_MAC_FILE_CHMOD:
+	case CCS_MAC_FILE_CHOWN:
+	case CCS_MAC_FILE_CHGRP:
+	case CCS_MAC_FILE_IOCTL:
+	case CCS_MAC_FILE_MKDIR:
+	case CCS_MAC_FILE_CREATE:
+	case CCS_MAC_FILE_MKFIFO:
+	case CCS_MAC_FILE_MKSOCK:
+	case CCS_MAC_FILE_MKBLOCK:
+	case CCS_MAC_FILE_MKCHAR:
+	case CCS_MAC_FILE_UMOUNT:
+		if (index == 0)
+			return "path";
+		break;
+	case CCS_MAC_ENVIRON:
+	case CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET:
+	case CCS_MAC_CAPABILITY_USE_PACKET_SOCKET:
+	case CCS_MAC_CAPABILITY_SYS_REBOOT:
+	case CCS_MAC_CAPABILITY_SYS_VHANGUP:
+	case CCS_MAC_CAPABILITY_SYS_SETTIME:
+	case CCS_MAC_CAPABILITY_SYS_NICE:
+	case CCS_MAC_CAPABILITY_SYS_SETHOSTNAME:
+	case CCS_MAC_CAPABILITY_USE_KERNEL_MODULE:
+	case CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD:
+		if (index == 0)
+			return "name";
+		break;
+	case CCS_MAC_NETWORK_INET_STREAM_BIND:
+        case CCS_MAC_NETWORK_INET_STREAM_LISTEN:
+        case CCS_MAC_NETWORK_INET_STREAM_CONNECT:
+        case CCS_MAC_NETWORK_INET_STREAM_ACCEPT:
+        case CCS_MAC_NETWORK_INET_DGRAM_BIND:
+        case CCS_MAC_NETWORK_INET_DGRAM_SEND:
+        case CCS_MAC_NETWORK_INET_DGRAM_RECV:
+        case CCS_MAC_NETWORK_INET_RAW_BIND:
+        case CCS_MAC_NETWORK_INET_RAW_SEND:
+        case CCS_MAC_NETWORK_INET_RAW_RECV:
+                if (index == 0)
+                        return "ip";
+		break;
+	case CCS_MAC_NETWORK_UNIX_STREAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_STREAM_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_STREAM_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_SEND:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_RECV:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT:
+		if (index == 0)
+			return "addr";
+		break;
+	case CCS_MAC_PTRACE:
+		if (index == 0)
+			return "domain";
+		break;
+	default:
+		break;
+	}
+	return "unknown"; /* This should not happen. */
+}
+
+/**
+ * ccs_get_narg - Get attribute name of CCS_NARG argument.
+ *
+ * @type:  One of values in "enum ccs_mac_index".
+ * @index: Index to return.
+ *
+ * Returns attribute name.
+ */
+static const char *ccs_get_narg(const enum ccs_mac_index type, const u8 index)
+{
+	switch (type) {
+        case CCS_MAC_FILE_MOUNT:
+	case CCS_MAC_FILE_UMOUNT:
+		if (index == 0)
+			return "flags";
+		break;
+	case CCS_MAC_FILE_CHMOD:
+		if (index == 0)
+			return "perm";
+		break;
+	case CCS_MAC_FILE_CHOWN:
+		if (index == 0)
+			return "uid";
+		break;
+	case CCS_MAC_FILE_CHGRP:
+		if (index == 0)
+			return "gid";
+		break;
+	case CCS_MAC_FILE_IOCTL:
+		if (index == 0)
+			return "cmd";
+		break;
+	case CCS_MAC_FILE_MKDIR:
+	case CCS_MAC_FILE_CREATE:
+	case CCS_MAC_FILE_MKFIFO:
+	case CCS_MAC_FILE_MKSOCK:
+		if (index == 0)
+			return "perm";
+		break;
+	case CCS_MAC_FILE_MKBLOCK:
+	case CCS_MAC_FILE_MKCHAR:
+		if (index == 0)
+			return "perm";
+		if (index == 1)
+			return "dev_major";
+		if (index == 2)
+			return "dev_minor";
+		break;
+	case CCS_MAC_NETWORK_INET_STREAM_BIND:
+        case CCS_MAC_NETWORK_INET_STREAM_LISTEN:
+        case CCS_MAC_NETWORK_INET_STREAM_CONNECT:
+        case CCS_MAC_NETWORK_INET_STREAM_ACCEPT:
+        case CCS_MAC_NETWORK_INET_DGRAM_BIND:
+        case CCS_MAC_NETWORK_INET_DGRAM_SEND:
+        case CCS_MAC_NETWORK_INET_DGRAM_RECV:
+                if (index == 0)
+                        return "port";
+		break;
+        case CCS_MAC_NETWORK_INET_RAW_BIND:
+        case CCS_MAC_NETWORK_INET_RAW_SEND:
+        case CCS_MAC_NETWORK_INET_RAW_RECV:
+                if (index == 0)
+			return "proto";
+		break;
+	case CCS_MAC_PTRACE:
+		if (index == 0)
+			return "cmd";
+		break;
+	default:
+		break;
+	}
+	return "unknown"; /* This should not happen. */
+}
+
 /***** SECTION5: Variables definition section *****/
 
 /* Permit policy management by non-root user? */
@@ -1165,16 +1272,16 @@
 /* Has /sbin/init started? */
 bool ccs_policy_loaded;
 
-/* List of namespaces. */
-LIST_HEAD(ccs_namespace_list);
-/* True if namespace other than ccs_kernel_namespace is defined. */
-static bool ccs_namespace_enabled;
-
-/* Initial namespace.*/
-static struct ccs_policy_namespace ccs_kernel_namespace;
 static struct ccs_path_info ccs_kernel_transition;
 
-struct ccs_group ccs_group_any;
+/* Profile table. Memory is allocated as needed. */
+static struct ccs_profile *ccs_profile_ptr[CCS_MAX_PROFILES];
+/* List of "struct ccs_group". */
+struct list_head ccs_group_list[CCS_MAX_GROUP];
+/* List of default transition pattern. */
+struct list_head ccs_default_transition_list;
+/* Profile version. Currently only 20100903 is defined. */
+static unsigned int ccs_profile_version;
 
 /* List of "struct ccs_condition". */
 LIST_HEAD(ccs_condition_list);
@@ -1321,8 +1428,6 @@
 				goto out;
 			c = *string++;
 			switch (c) {
-			case '\\':  /* "\\" */
-				continue;
 			case '$':   /* "\$" */
 			case '+':   /* "\+" */
 			case '?':   /* "\?" */
@@ -1357,7 +1462,7 @@
 				if (d < '0' || d > '7' || e < '0' || e > '7')
 					break;
 				c = ccs_make_byte(c, d, e);
-				if (c <= ' ' || c >= 127)
+				if (c <= ' ' || c >= 127 || c == '\\')
 					continue;
 			}
 			goto out;
@@ -1402,8 +1507,6 @@
 	struct list_head *list;
 	const char *group_name = ccs_read_token(param);
 	bool found = false;
-	if (!strcmp(group_name, "any"))
-		return &ccs_group_any;
 	if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
 		return NULL;
 	e.group_name = ccs_get_name(group_name);
@@ -1411,7 +1514,7 @@
 		return NULL;
 	if (mutex_lock_interruptible(&ccs_policy_lock))
 		goto out;
-	list = &param->ns->group_list[idx];
+	list = &ccs_group_list[idx];
 	list_for_each_entry(group, list, head.list) {
 		if (e.group_name != group->group_name ||
 		    atomic_read(&group->head.users) == CCS_GC_IN_PROGRESS)
@@ -1437,33 +1540,6 @@
 }
 
 /**
- * ccs_parse_name_union - Parse a ccs_name_union.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_name_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_name_union(struct ccs_acl_param *param,
-				 struct ccs_name_union *ptr)
-{
-	char *filename;
-	switch (ccs_group_type(&param->data)) {
-	case 2:
-		ptr->is_not = true;
-		/* fall through */
-	case 1:
-		ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
-		return ptr->group != NULL;
-	}
-	filename = ccs_read_token(param);
-	if (!ccs_correct_word(filename))
-		return false;
-	ptr->filename = ccs_get_name(filename);
-	return ptr->filename != NULL;
-}
-
-/**
  * ccs_parse_ulong - Parse an "unsigned long" value.
  *
  * @result: Pointer to "unsigned long".
@@ -1504,100 +1580,6 @@
 }
 
 /**
- * ccs_parse_number_union - Parse a ccs_number_union.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_number_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_number_union(struct ccs_acl_param *param,
-				   struct ccs_number_union *ptr)
-{
-	char *data;
-	u8 type;
-	unsigned long v;
-	memset(ptr, 0, sizeof(*ptr));
-	switch (ccs_group_type(&param->data)) {
-	case 2:
-		ptr->is_not = true;
-		/* fall through */
-	case 1:
-		ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
-		return ptr->group != NULL;
-	}
-	data = ccs_read_token(param);
-	type = ccs_parse_ulong(&v, &data);
-	if (type == CCS_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 = ccs_parse_ulong(&v, &data);
-	if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
-		return false;
-	ptr->values[1] = v;
-	ptr->value_type[1] = type;
-	return true;
-}
-
-#ifdef CONFIG_CCSECURITY_NETWORK
-
-/**
- * ccs_parse_ipaddr_union - Parse an IP address.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_ipaddr_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
-				   struct ccs_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;
-	const char *end;
-	switch (ccs_group_type(&param->data)) {
-	case 2:
-		ptr->is_not = true;
-		/* fall through */
-	case 1:
-		ptr->group = ccs_get_group(param, CCS_ADDRESS_GROUP);
-		return ptr->group != NULL;
-	}
-	address = ccs_read_token(param);
-	if (!strchr(address, ':') &&
-	    ccs_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++ != '-' ||
-			 ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
-			return false;
-		return true;
-	}
-	if (ccs_in6_pton(address, -1, min, '-', &end) > 0) {
-		ptr->is_ipv6 = true;
-		if (!*end)
-			memmove(max, min, sizeof(u16) * 8);
-		else if (*end++ != '-' ||
-			 ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
-			return false;
-		return true;
-	}
-	return false;
-}
-
-#endif
-
-/**
  * ccs_get_dqword - ccs_get_name() for a quoted string.
  *
  * @start: String to save.
@@ -1616,80 +1598,6 @@
 }
 
 /**
- * ccs_parse_name_union_quoted - Parse a quoted word.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_name_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
-					struct ccs_name_union *ptr)
-{
-	char *filename = param->data;
-	if (ccs_group_type(&filename))
-		return ccs_parse_name_union(param, ptr);
-	ptr->filename = ccs_get_dqword(filename);
-	return ptr->filename != NULL;
-}
-
-/**
- * ccs_parse_argv - Parse an argv[] condition part.
- *
- * @left:  Lefthand value.
- * @right: Righthand value.
- * @argv:  Pointer to "struct ccs_argv".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
-{
-	if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL ||
-	    *left++ != ']' || *left)
-		return false;
-	argv->value = ccs_get_dqword(right);
-	return argv->value != NULL;
-}
-
-/**
- * ccs_parse_envp - Parse an envp[] condition part.
- *
- * @left:  Lefthand value.
- * @right: Righthand value.
- * @envp:  Pointer to "struct ccs_envp".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
-{
-	const struct ccs_path_info *name;
-	const struct ccs_path_info *value;
-	char *cp = left + strlen(left) - 1;
-	if (*cp-- != ']' || *cp != '"')
-		goto out;
-	*cp = '\0';
-	if (!ccs_correct_word(left))
-		goto out;
-	name = ccs_get_name(left);
-	if (!name)
-		goto out;
-	if (!strcmp(right, "NULL")) {
-		value = NULL;
-	} else {
-		value = ccs_get_dqword(right);
-		if (!value) {
-			ccs_put_name(name);
-			goto out;
-		}
-	}
-	envp->name = name;
-	envp->value = value;
-	return true;
-out:
-	return false;
-}
-
-/**
  * ccs_same_condition - Check for duplicated "struct ccs_condition" entry.
  *
  * @a: Pointer to "struct ccs_condition".
@@ -1700,33 +1608,11 @@
 static bool ccs_same_condition(const struct ccs_condition *a,
 			       const struct ccs_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 &&
-		!memcmp(a + 1, b + 1, a->size - sizeof(*a));
+       return a->size == b->size &&
+	       !memcmp(a + 1, b + 1, a->size - sizeof(*a));
 }
 
 /**
- * ccs_condition_type - Get condition type.
- *
- * @word: Keyword string.
- *
- * Returns one of values in "enum ccs_conditions_index" on success,
- * CCS_MAX_CONDITION_KEYWORD otherwise.
- */
-static u8 ccs_condition_type(const char *word)
-{
-	u8 i;
-	for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) {
-		if (!strcmp(word, ccs_condition_keyword[i]))
-			break;
-	}
-	return i;
-}
-
-/**
  * ccs_commit_condition - Commit "struct ccs_condition".
  *
  * @entry: Pointer to "struct ccs_condition".
@@ -1787,29 +1673,6 @@
 }
 
 /**
- * ccs_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.
- */
-static bool ccs_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] != '>' || !ccs_correct_word2(buffer + 1, len - 2))
-		return false;
-	return true;
-}
-
-/**
  * ccs_correct_domain - Check whether the given domainname follows the naming rules.
  *
  * @domainname: The domainname to check.
@@ -1818,21 +1681,27 @@
  */
 static bool ccs_correct_domain(const unsigned char *domainname)
 {
-	if (!domainname || !ccs_domain_def(domainname))
+	if (!domainname || *domainname != '<')
 		return false;
-	domainname = strchr(domainname, ' ');
-	if (!domainname++)
-		return true;
+	{
+		int len;
+		const unsigned char *cp = strstr(domainname, "\\_");
+		if (!cp)
+			len = strlen(domainname);
+		else
+			len = cp - domainname;
+		if (domainname[len - 1] != '>')
+			return false;
+	}
 	while (1) {
-		const unsigned char *cp = strchr(domainname, ' ');
+		const unsigned char *cp = strstr(domainname, "\\_");
 		if (!cp)
 			break;
-		if (*domainname != '/' ||
-		    !ccs_correct_word2(domainname, cp - domainname))
+		if (!ccs_correct_word2(domainname, cp - domainname))
 			return false;
-		domainname = cp + 1;
+		domainname = cp + 2;
 	}
-	return ccs_correct_path(domainname);
+	return ccs_correct_word(domainname);
 }
 
 /**
@@ -1864,64 +1733,561 @@
 	*dp = '\0';
 }
 
-/**
- * ccs_get_domainname - Read a domainname from a line.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns a domainname on success, NULL otherwise.
- */
-static const struct ccs_path_info *ccs_get_domainname
-(struct ccs_acl_param *param)
+struct ccs_cond_tmp {
+	u8 left;
+	u8 right;
+	bool equals;
+	u8 radix;
+	struct ccs_group *group;
+	const struct ccs_path_info *path;
+	struct in6_addr ipv6[2];
+	unsigned long value[2];
+	unsigned long argv;
+	const struct ccs_path_info *envp;
+};
+
+static u8 ccs_parse_values(char *value, unsigned long v[2])
 {
-	char *start = param->data;
-	char *pos = start;
-	while (*pos) {
-		if (*pos++ != ' ' || *pos++ == '/')
-			continue;
-		pos -= 2;
-		*pos++ = '\0';
+	u8 radix1 = ccs_parse_ulong(&v[0], &value);
+	u8 radix2;
+	if (radix1 == CCS_VALUE_TYPE_INVALID)
+		return CCS_VALUE_TYPE_INVALID;
+	if (!*value) {
+		v[1] = v[0];
+		return radix1;
+	}
+	if (*value++ != '-')
+		return CCS_VALUE_TYPE_INVALID;
+	radix2 = ccs_parse_ulong(&v[1], &value);
+	if (radix2 == CCS_VALUE_TYPE_INVALID || *value || v[0] > v[1])
+		return CCS_VALUE_TYPE_INVALID;
+	return radix1 | (radix2 << 2);
+}
+
+static u8 ccs_parse_ipaddr(char *address, struct in6_addr ipv6[2])
+{
+	const char *end;
+	if (!strchr(address, ':') &&
+	    ccs_in4_pton(address, -1, ipv6[0].s6_addr, '-', &end) > 0) {
+		if (!*end) {
+			ipv6[0].s6_addr32[0] = ipv6[0].s6_addr32[0];
+			return 1;
+		}
+		if (*end++ != '-' ||
+		    ccs_in4_pton(end, -1, ipv6[1].s6_addr, '\0', &end) <= 0 ||
+		    *end || memcmp(&ipv6[0], &ipv6[1], 4) >= 0)
+			return 0;
+		return 2;
+	}
+	if (ccs_in6_pton(address, -1, ipv6[0].s6_addr, '-', &end) > 0) {
+		if (!*end) {
+			ipv6[1] = ipv6[0];
+			return 3;
+		}
+		if (*end++ != '-' ||
+		    ccs_in6_pton(end, -1, ipv6[1].s6_addr, '\0', &end) <= 0 ||
+		    *end || memcmp(&ipv6[0], &ipv6[1], 16) >= 0)
+			return 0;
+		return 4;
+	}
+	return 0;
+}
+
+static enum ccs_conditions_index ccs_parse_task_cond(const char *word)
+{
+	if (!strncmp(word, "task.", 5)) {
+		word += 5;
+		if (!strcmp(word, "uid"))
+			return CCS_SELF_UID;
+		if (!strcmp(word, "euid"))
+			return  CCS_SELF_EUID;
+		if (!strcmp(word, "suid"))
+			return CCS_SELF_SUID;
+		if (!strcmp(word, "fsuid"))
+			return  CCS_SELF_FSUID;
+		if (!strcmp(word, "gid"))
+			return CCS_SELF_GID;
+		if (!strcmp(word, "egid"))
+			return CCS_SELF_EGID;
+		if (!strcmp(word, "sgid"))
+			return CCS_SELF_SGID;
+		if (!strcmp(word, "fsgid"))
+			return CCS_SELF_FSGID;
+		if (!strcmp(word, "pid"))
+			return CCS_SELF_PID;
+		if (!strcmp(word, "ppid"))
+			return CCS_SELF_PPID;
+		if (!strcmp(word, "type"))
+			return CCS_TASK_TYPE;
+		if (!strcmp(word, "domain"))
+			return CCS_SELF_DOMAIN;
+	}
+	return CCS_MAX_CONDITION_KEYWORD;
+}
+
+static enum ccs_conditions_index ccs_parse_syscall_arg
+(const char *word, const enum ccs_mac_index type)
+{
+	switch (type) {
+	case CCS_MAC_FILE_READ:
+	case CCS_MAC_FILE_WRITE:
+	case CCS_MAC_FILE_APPEND:
+	case CCS_MAC_FILE_UNLINK:
+	case CCS_MAC_FILE_GETATTR:
+	case CCS_MAC_FILE_RMDIR:
+	case CCS_MAC_FILE_TRUNCATE:
+	case CCS_MAC_FILE_CHROOT:
+	case CCS_MAC_FILE_CHOWN:
+	case CCS_MAC_FILE_CHGRP:
+	case CCS_MAC_FILE_IOCTL:
+	case CCS_MAC_FILE_EXECUTE:
+	case CCS_MAC_FILE_SYMLINK:
+		if (!strcmp(word, "path"))
+			return CCS_COND_SARG0;
+		if (type == CCS_MAC_FILE_CHOWN && !strcmp(word, "uid"))
+			return CCS_COND_NARG0;
+		if (type == CCS_MAC_FILE_CHGRP && !strcmp(word, "gid"))
+			return CCS_COND_NARG0;
+		if (type == CCS_MAC_FILE_IOCTL && !strcmp(word, "cmd"))
+			return CCS_COND_NARG0;
+		if (type == CCS_MAC_FILE_EXECUTE && !strcmp(word, "exec"))
+			return CCS_COND_SARG1;
+		if (type == CCS_MAC_FILE_SYMLINK && !strcmp(word, "target"))
+			return CCS_COND_SARG1;
 		break;
+	case CCS_MAC_FILE_CHMOD:
+	case CCS_MAC_FILE_MKDIR:
+	case CCS_MAC_FILE_CREATE:
+	case CCS_MAC_FILE_MKFIFO:
+	case CCS_MAC_FILE_MKSOCK:
+	case CCS_MAC_FILE_MKBLOCK:
+	case CCS_MAC_FILE_MKCHAR:
+		if (!strcmp(word, "path"))
+			return CCS_COND_SARG0;
+		if (!strcmp(word, "perm"))
+			return CCS_COND_NARG0;
+		if (type == CCS_MAC_FILE_MKBLOCK ||
+		    type == CCS_MAC_FILE_MKCHAR) {
+			if (!strcmp(word, "dev_major"))
+				return CCS_COND_NARG1;
+			if (!strcmp(word, "dev_minor"))
+				return CCS_COND_NARG2;
+		}
+		break;
+	case CCS_MAC_FILE_LINK:
+	case CCS_MAC_FILE_RENAME:
+		if (!strcmp(word, "old_path"))
+			return CCS_COND_SARG0;
+		if (!strcmp(word, "new_path"))
+			return CCS_COND_SARG1;
+		break;
+	case CCS_MAC_FILE_MOUNT:
+		if (!strcmp(word, "source"))
+			return CCS_COND_SARG0;
+		if (!strcmp(word, "target"))
+			return CCS_COND_SARG1;
+		if (!strcmp(word, "fstype"))
+			return CCS_COND_SARG2;
+		if (!strcmp(word, "flags"))
+			return CCS_COND_NARG0;
+		break;
+	case CCS_MAC_FILE_UMOUNT:
+		if (!strcmp(word, "path"))
+			return CCS_COND_SARG0;
+		if (!strcmp(word, "flags"))
+			return CCS_COND_NARG0;
+		break;
+	case CCS_MAC_FILE_PIVOT_ROOT:
+		if (!strcmp(word, "new_root"))
+			return CCS_COND_SARG0;
+		if (!strcmp(word, "put_old"))
+			return CCS_COND_SARG1;
+		break;
+	case CCS_MAC_NETWORK_INET_STREAM_BIND:
+	case CCS_MAC_NETWORK_INET_STREAM_LISTEN:
+	case CCS_MAC_NETWORK_INET_STREAM_CONNECT:
+	case CCS_MAC_NETWORK_INET_STREAM_ACCEPT:
+	case CCS_MAC_NETWORK_INET_DGRAM_BIND:
+	case CCS_MAC_NETWORK_INET_DGRAM_SEND:
+	case CCS_MAC_NETWORK_INET_DGRAM_RECV:
+		if (!strcmp(word, "ip"))
+			return CCS_COND_IPARG;
+		if (!strcmp(word, "port"))
+			return CCS_COND_NARG0;
+		break;
+	case CCS_MAC_NETWORK_INET_RAW_BIND:
+	case CCS_MAC_NETWORK_INET_RAW_SEND:
+	case CCS_MAC_NETWORK_INET_RAW_RECV:
+		if (!strcmp(word, "ip"))
+			return CCS_COND_IPARG;
+		if (!strcmp(word, "proto"))
+			return CCS_COND_NARG0;
+		break;
+	case CCS_MAC_NETWORK_UNIX_STREAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_STREAM_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_STREAM_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_SEND:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_RECV:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT:
+		if (!strcmp(word, "addr"))
+			return CCS_COND_SARG0;
+		break;
+	case CCS_MAC_ENVIRON:
+		if (!strcmp(word, "name"))
+			return CCS_COND_SARG0;
+		break;
+	case CCS_MAC_PTRACE:
+		if (!strcmp(word, "domain"))
+			return CCS_COND_DOMAIN;
+		break;
+	case CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET:
+	case CCS_MAC_CAPABILITY_USE_PACKET_SOCKET:
+	case CCS_MAC_CAPABILITY_SYS_REBOOT:
+	case CCS_MAC_CAPABILITY_SYS_VHANGUP:
+	case CCS_MAC_CAPABILITY_SYS_SETTIME:
+	case CCS_MAC_CAPABILITY_SYS_NICE:
+	case CCS_MAC_CAPABILITY_SYS_SETHOSTNAME:
+	case CCS_MAC_CAPABILITY_USE_KERNEL_MODULE:
+	case CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD:
+		break;
+	case CCS_MAX_MAC_INDEX:
+	case CCS_MAC_AUTO_EXECUTE_HANDLER:
+	case CCS_MAC_DENIED_EXECUTE_HANDLER:
+	case CCS_MAC_AUTO_TASK_TRANSITION:
+	case CCS_MAC_MANUAL_TASK_TRANSITION:
+	case CCS_MAC_USE_GROUP:
+		break;
 	}
-	param->data = pos;
-	if (ccs_correct_domain(start))
-		return ccs_get_name(start);
-	return NULL;
+	return CCS_MAX_CONDITION_KEYWORD;
 }
 
-/**
- * ccs_get_transit_preference - Parse domain transition preference for execve().
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @e:     Pointer to "struct ccs_condition".
- *
- * Returns the condition string part.
- */
-static char *ccs_get_transit_preference(struct ccs_acl_param *param,
-					struct ccs_execute_acl *e)
+static enum ccs_conditions_index ccs_parse_path_attribute
+(char *word, const enum ccs_mac_index type)
 {
-	char * const pos = param->data;
-	bool flag;
-	if (*pos == '<') {
-		e->transit = ccs_get_domainname(param);
-		goto done;
+	u8 i;
+	enum ccs_conditions_index start;
+	static const char *const ccs_path_attribute[CCS_MAX_PATH_ATTRIBUTE] = {
+		[CCS_PATH_ATTRIBUTE_UID]       = "uid",
+		[CCS_PATH_ATTRIBUTE_GID]       = "gid",
+		[CCS_PATH_ATTRIBUTE_INO]       = "ino",
+		[CCS_PATH_ATTRIBUTE_MAJOR]     = "major",
+		[CCS_PATH_ATTRIBUTE_MINOR]     = "minor",
+		[CCS_PATH_ATTRIBUTE_PERM]      = "perm",
+		[CCS_PATH_ATTRIBUTE_TYPE]      = "type",
+		[CCS_PATH_ATTRIBUTE_DEV_MAJOR] = "dev_major",
+		[CCS_PATH_ATTRIBUTE_DEV_MINOR] = "dev_minor",
+	};
+	switch (type) {
+	case CCS_MAC_FILE_READ:
+	case CCS_MAC_FILE_WRITE:
+	case CCS_MAC_FILE_APPEND:
+	case CCS_MAC_FILE_UNLINK:
+	case CCS_MAC_FILE_GETATTR:
+	case CCS_MAC_FILE_RMDIR:
+	case CCS_MAC_FILE_TRUNCATE:
+	case CCS_MAC_FILE_CHROOT:
+	case CCS_MAC_FILE_CHMOD:
+	case CCS_MAC_FILE_CHOWN:
+	case CCS_MAC_FILE_CHGRP:
+	case CCS_MAC_FILE_IOCTL:
+	case CCS_MAC_FILE_EXECUTE:
+	case CCS_MAC_FILE_UMOUNT:
+		if (ccs_str_starts(&word, "path"))
+			goto path1;
+		break;
+	case CCS_MAC_FILE_MKDIR:
+	case CCS_MAC_FILE_CREATE:
+	case CCS_MAC_FILE_MKFIFO:
+	case CCS_MAC_FILE_MKSOCK:
+	case CCS_MAC_FILE_MKBLOCK:
+	case CCS_MAC_FILE_MKCHAR:
+	case CCS_MAC_FILE_SYMLINK:
+		if (ccs_str_starts(&word, "path"))
+			goto path1_parent;
+		break;
+	case CCS_MAC_FILE_LINK:
+	case CCS_MAC_FILE_RENAME:
+		if (ccs_str_starts(&word, "old_path"))
+			goto path1;
+		if (ccs_str_starts(&word, "new_path"))
+			goto path2_parent;
+		break;
+	case CCS_MAC_FILE_MOUNT:
+		if (ccs_str_starts(&word, "source"))
+			goto path1;
+		if (ccs_str_starts(&word, "target"))
+			goto path2;
+		break;
+	case CCS_MAC_FILE_PIVOT_ROOT:
+		if (ccs_str_starts(&word, "new_root"))
+			goto path1;
+		if (ccs_str_starts(&word, "put_old"))
+			goto path2;
+		break;
+	default:
+		break;
 	}
-	{
-		char *cp = strchr(pos, ' ');
-		if (cp)
+	goto out;
+path1_parent:
+	if (strncmp(word, ".parent", 7))
+		goto out;
+path1:
+	start = CCS_PATH_ATTRIBUTE_START;
+	goto check;
+path2_parent:
+	if (strncmp(word, ".parent", 7))
+		goto out;
+path2:
+	start = CCS_PATH_ATTRIBUTE_START + 32;
+check:
+	if (ccs_str_starts(&word, ".parent"))
+		start += 16;
+	if (*word++ == '.')
+		for (i = 0; i < CCS_MAX_PATH_ATTRIBUTE; i++)
+			if (!strcmp(word, ccs_path_attribute[i]))
+				return start + i;
+out:
+	return CCS_MAX_CONDITION_KEYWORD;
+}
+
+static enum ccs_conditions_index ccs_find_path_type(const char *word)
+{
+	if (!strcmp(word, "socket"))
+		return CCS_OBJ_IS_SOCKET;
+	if (!strcmp(word, "symlink"))
+		return CCS_OBJ_IS_SYMLINK;
+	if (!strcmp(word, "file"))
+		return CCS_OBJ_IS_FILE;
+	if (!strcmp(word, "block"))
+		return CCS_OBJ_IS_BLOCK_DEV;
+	if (!strcmp(word, "directory"))
+		return CCS_OBJ_IS_DIRECTORY;
+	if (!strcmp(word, "char"))
+		return CCS_OBJ_IS_CHAR_DEV;
+	if (!strcmp(word, "fifo"))
+		return CCS_OBJ_IS_FIFO;
+	return CCS_MAX_CONDITION_KEYWORD;
+}
+
+static enum ccs_conditions_index ccs_find_path_perm(const char *word)
+{
+	if (!strcmp(word, "setuid"))
+		return CCS_MODE_SETUID;
+	if (!strcmp(word, "setgid"))
+		return CCS_MODE_SETGID;
+	if (!strcmp(word, "sticky"))
+		return CCS_MODE_STICKY;
+	if (!strcmp(word, "owner_read"))
+		return CCS_MODE_OWNER_READ;
+	if (!strcmp(word, "owner_write"))
+		return CCS_MODE_OWNER_WRITE;
+	if (!strcmp(word, "owner_execute"))
+		return CCS_MODE_OWNER_EXECUTE;
+	if (!strcmp(word, "group_read"))
+		return CCS_MODE_GROUP_READ;
+	if (!strcmp(word, "group_write"))
+		return CCS_MODE_GROUP_WRITE;
+	if (!strcmp(word, "group_execute"))
+		return CCS_MODE_GROUP_EXECUTE;
+	if (!strcmp(word, "others_read"))
+		return CCS_MODE_OTHERS_READ;
+	if (!strcmp(word, "others_write"))
+		return CCS_MODE_OTHERS_WRITE;
+	if (!strcmp(word, "others_execute"))
+		return CCS_MODE_OTHERS_EXECUTE;
+	return CCS_MAX_CONDITION_KEYWORD;
+}
+	
+static bool ccs_parse_cond(struct ccs_cond_tmp *tmp,
+			   struct ccs_acl_param *param)
+{
+	enum ccs_group_id g;
+	char *left = param->data;
+	char *right;// = strchr(left, ' ');
+	const enum ccs_mac_index type = param->e.acl_info.type;
+	memset(tmp, 0, sizeof(*tmp));
+	tmp->left = CCS_MAX_CONDITION_KEYWORD;
+	tmp->right = CCS_MAX_CONDITION_KEYWORD;
+	//if (right)
+	//*right = '\0';
+	right = strchr(left, '=');
+	if (!right || right == left)
+		return false;
+	*right++ = '\0';
+	tmp->equals = *(right - 2) != '!';
+	if (!tmp->equals)
+		*(right - 2) = '\0';
+	if (!*left || !*right)
+		return false;
+	//printk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left,
+	//       tmp->equals ? "" : "!", right);
+	if (type == CCS_MAC_FILE_EXECUTE || type == CCS_MAC_ENVIRON) {
+		if (ccs_str_starts(&left, "argv[")) {
+			tmp->left = CCS_ARGV_ENTRY;
+			if (ccs_parse_ulong(&tmp->argv, &left) !=
+			    CCS_VALUE_TYPE_DECIMAL || *left++ != ']' || *left)
+				goto out;
+		} else if (ccs_str_starts(&left, "envp[\"")) {
+			char *cp = left + strlen(left) - 1;
+			tmp->left = CCS_ENVP_ENTRY;
+			if (*cp-- != ']' || *cp != '"')
+				goto out;
 			*cp = '\0';
-		flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
-			!strcmp(pos, "child");
-		if (cp)
-			*cp = ' ';
+			if (!ccs_correct_word(left))
+				goto out;
+			tmp->envp = ccs_get_name(left);
+			if (!tmp->envp)
+				goto out;
+		} else if (!strcmp(left, "argc"))
+			tmp->left = CCS_EXEC_ARGC;
+		else if (!strcmp(left, "envc"))
+			tmp->left = CCS_EXEC_ENVC;
 	}
-	if (!flag)
-		return pos;
-	e->transit = ccs_get_name(ccs_read_token(param));
-done:
-	if (e->transit)
-		return param->data;
-	return NULL;
+	if (tmp->left == CCS_MAX_CONDITION_KEYWORD)
+		tmp->left = ccs_parse_syscall_arg(left, type);
+	if (tmp->left == CCS_MAX_CONDITION_KEYWORD)
+		tmp->left = ccs_parse_task_cond(left);
+	if (tmp->left == CCS_MAX_CONDITION_KEYWORD)
+		tmp->left = ccs_parse_path_attribute(left, type);
+	if (tmp->left == CCS_MAX_CONDITION_KEYWORD) {
+		if (!strcmp(left, "handler"))
+			tmp->left = CCS_HANDLER_PATH;
+		else if (!strcmp(left, "transition"))
+			tmp->left = CCS_TRANSIT_DOMAIN;
+	}
+	if (tmp->left == CCS_MAX_CONDITION_KEYWORD)
+		goto out;
+	switch (tmp->left) {
+	case CCS_HANDLER_PATH:
+		if (!tmp->equals)
+			goto out;
+		tmp->right = CCS_IMM_NAME_ENTRY;
+		tmp->path = ccs_get_dqword(right);
+		if (!tmp->path || tmp->path->is_patterned)
+			goto out;
+		return true;
+	case CCS_TRANSIT_DOMAIN:
+		if (!tmp->equals)
+			goto out;
+		tmp->right = CCS_IMM_DOMAINNAME_ENTRY;
+		if (!strcmp(right, "keep") ||
+		    !strcmp(right, "child") ||
+		    ccs_correct_path(right) ||
+		    ccs_correct_domain(right))
+			tmp->path = ccs_get_name(right);
+		if (!tmp->path)
+			goto out;
+		return true;
+	case CCS_COND_DOMAIN:
+	case CCS_SELF_DOMAIN:
+		tmp->right = CCS_IMM_DOMAINNAME_ENTRY;
+		if (ccs_correct_domain(right))
+			tmp->path = ccs_get_name(right);
+		if (!tmp->path)
+			goto out;
+		return true;
+	case CCS_ARGV_ENTRY:
+	case CCS_ENVP_ENTRY:
+	case CCS_COND_SARG0:
+	case CCS_COND_SARG1:
+	case CCS_COND_SARG2:
+		g = CCS_PATH_GROUP;
+		break;
+	case CCS_COND_IPARG:
+		g = CCS_ADDRESS_GROUP;
+		break;
+	case CCS_TASK_TYPE:
+		if (!strcmp(right, "execute_handler"))
+			goto out;
+		tmp->right = CCS_TASK_EXECUTE_HANDLER;
+		return true;
+	case CCS_PATH_ATTRIBUTE_START + CCS_PATH_ATTRIBUTE_TYPE:
+	case CCS_PATH_ATTRIBUTE_START + 16 + CCS_PATH_ATTRIBUTE_TYPE:
+	case CCS_PATH_ATTRIBUTE_START + 32 + CCS_PATH_ATTRIBUTE_TYPE:
+	case CCS_PATH_ATTRIBUTE_START + 48 + CCS_PATH_ATTRIBUTE_TYPE:
+		tmp->right = ccs_find_path_type(right);
+		if (tmp->right != CCS_MAX_CONDITION_KEYWORD)
+			return true;
+		goto out;
+	case CCS_PATH_ATTRIBUTE_START + CCS_PATH_ATTRIBUTE_PERM:
+	case CCS_PATH_ATTRIBUTE_START + 16 + CCS_PATH_ATTRIBUTE_PERM:
+	case CCS_PATH_ATTRIBUTE_START + 32 + CCS_PATH_ATTRIBUTE_PERM:
+	case CCS_PATH_ATTRIBUTE_START + 48 + CCS_PATH_ATTRIBUTE_PERM:
+		tmp->right = ccs_find_path_perm(right);
+		if (tmp->right != CCS_MAX_CONDITION_KEYWORD)
+			return true;
+		/* fall through */
+	default:
+		g = CCS_NUMBER_GROUP;
+	}
+	if (*right == '@') {
+		tmp->right = CCS_IMM_GROUP;
+		param->data = ++right;
+		tmp->group = ccs_get_group(param, g);
+		if (!tmp->group)
+			goto out;
+	} else if (*right == '"') {
+		if (g != CCS_PATH_GROUP)
+			goto out;
+		tmp->right = CCS_IMM_NAME_ENTRY;
+		tmp->path = ccs_get_dqword(right);
+		if (!tmp->path)
+			goto out;
+	} else if (tmp->left == CCS_ENVP_ENTRY) {
+		tmp->right = CCS_IMM_NAME_ENTRY;
+		if (strcmp(right, "NULL"))
+			goto out;
+	} else if (g == CCS_NUMBER_GROUP) {
+		tmp->right = ccs_parse_task_cond(right);
+		if (tmp->right == CCS_SELF_DOMAIN)
+			goto out;
+		if (tmp->right == CCS_MAX_CONDITION_KEYWORD)
+			tmp->right = ccs_parse_path_attribute(right, type);
+		if (tmp->right != CCS_MAX_CONDITION_KEYWORD)
+			return true;
+		tmp->radix = ccs_parse_values(right, tmp->value);
+		if (tmp->radix == CCS_VALUE_TYPE_INVALID)
+			goto out;
+		if (tmp->radix >> 2)
+			tmp->right = CCS_IMM_NUMBER_ENTRY2;
+		else
+			tmp->right = CCS_IMM_NUMBER_ENTRY1;
+	} else if (g == CCS_ADDRESS_GROUP) {
+		switch (ccs_parse_ipaddr(right, tmp->ipv6)) {
+		case 1:
+			tmp->right = CCS_IMM_IPV4ADDR_ENTRY1;
+			break;
+		case 2:
+			tmp->right = CCS_IMM_IPV4ADDR_ENTRY2;
+			break;
+		case 3:
+			tmp->right = CCS_IMM_IPV6ADDR_ENTRY1;
+			break;
+		case 4:
+			tmp->right = CCS_IMM_IPV6ADDR_ENTRY2;
+			break;
+		default:
+			goto out;
+		}
+	} else
+		goto out;
+	return true;
+out:
+	/*
+	printk(KERN_WARNING "%u: type=%u env='%s' path='%s' group='%s'\n",
+	       __LINE__, type, tmp->envp ? tmp->envp->name : "",
+	       tmp->path ? tmp->path->name : "",
+	       tmp->group ? tmp->group->group_name->name : "");
+	*/
+	ccs_put_name(tmp->envp);
+	ccs_put_name(tmp->path);
+	ccs_put_group(tmp->group);
+	return false;
 }
 
 /**
@@ -1933,201 +2299,119 @@
  */
 struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param)
 {
-	struct ccs_condition *entry = NULL;
-	struct ccs_condition_element *condp = NULL;
-	struct ccs_number_union *numbers_p = NULL;
-	struct ccs_name_union *names_p = NULL;
-	struct ccs_argv *argv = NULL;
-	struct ccs_envp *envp = NULL;
-	struct ccs_condition e = { };
-	char * const start_of_string = param->data;
-	char * const end_of_string = start_of_string + strlen(start_of_string);
-	char *pos;
-rerun:
-	pos = start_of_string;
+	struct ccs_condition *entry = kmalloc(PAGE_SIZE, CCS_GFP_FLAGS);
+	union ccs_condition_element *condp;
+	struct ccs_cond_tmp tmp;
+	bool handler_path_done =
+		param->e.acl_info.type != CCS_MAC_AUTO_EXECUTE_HANDLER &&
+		param->e.acl_info.type != CCS_MAC_DENIED_EXECUTE_HANDLER;
+	bool transit_domain_done =
+		param->e.acl_info.type != CCS_MAC_FILE_EXECUTE &&
+		handler_path_done;
+	char *pos = param->data;
+	if (!entry)
+		return NULL;
+	//entry->size = sizeof(*entry);
+	condp = (union ccs_condition_element *) (entry + 1);
 	while (1) {
-		u8 left = -1;
-		u8 right = -1;
-		char *left_word = pos;
-		char *cp;
-		char *right_word;
-		bool is_not;
-		if (!*left_word)
+		while (*pos == ' ')
+			pos++;
+		if (!*pos)
 			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 = "";
+		{
+			char *next = strchr(pos, ' ');
+			if (next)
+				*next++ = '\0';
+			else
+				next = "";
+			param->data = pos;
+			pos = next;
 		}
-		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 != CCS_GRANTLOG_AUTO)
-					goto out;
-				else if (!strcmp(right_word, "yes"))
-					entry->grant_log = CCS_GRANTLOG_YES;
-				else if (!strcmp(right_word, "no"))
-					entry->grant_log = CCS_GRANTLOG_NO;
-				else
-					goto out;
+		{
+			//char *word = kstrdup(param->data, GFP_KERNEL); 
+			if (!ccs_parse_cond(&tmp, param)) {
+				/*
+				printk(KERN_WARNING "%u: '%s' failed\n",
+				       __LINE__, word);
+				kfree(word);
+				*/
+				goto out;
 			}
-			continue;
+			//kfree(word);
 		}
-		if (!strncmp(left_word, "exec.argv[", 10)) {
-			if (!argv) {
-				e.argc++;
-				e.condc++;
-			} else {
-				e.argc--;
-				e.condc--;
-				left = CCS_ARGV_ENTRY;
-				argv->is_not = is_not;
-				if (!ccs_parse_argv(left_word + 10,
-						    right_word, argv++))
-					goto out;
-			}
-			goto store_value;
+		if (tmp.left == CCS_HANDLER_PATH) {
+			if (handler_path_done)
+				goto out;
+			handler_path_done = true;
 		}
-		if (!strncmp(left_word, "exec.envp[\"", 11)) {
-			if (!envp) {
-				e.envc++;
-				e.condc++;
-			} else {
-				e.envc--;
-				e.condc--;
-				left = CCS_ENVP_ENTRY;
-				envp->is_not = is_not;
-				if (!ccs_parse_envp(left_word + 11,
-						    right_word, envp++))
-					goto out;
-			}
-			goto store_value;
+		if (tmp.left == CCS_TRANSIT_DOMAIN) {
+			if (transit_domain_done)
+				goto out;
+			transit_domain_done = true;
 		}
-		left = ccs_condition_type(left_word);
-		dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
-			left);
-		if (left == CCS_MAX_CONDITION_KEYWORD) {
-			if (!numbers_p) {
-				e.numbers_count++;
-			} else {
-				e.numbers_count--;
-				left = CCS_NUMBER_UNION;
-				param->data = left_word;
-				if (ccs_group_type(&left_word) ||
-				    !ccs_parse_number_union(param,
-							    numbers_p++))
-					goto out;
-			}
+		if ((u8 *) condp >= ((u8 *) entry) + PAGE_SIZE
+		    - sizeof(*condp) + 32)
+			goto out;
+		condp->equals = tmp.equals;
+		condp->left = tmp.left;
+		condp->right = tmp.right;
+		condp->radix = tmp.radix;
+		condp++;
+		if (tmp.left == CCS_ARGV_ENTRY) {
+			condp->value = tmp.argv;
+			condp++;
+		} else if (tmp.left == CCS_ENVP_ENTRY) {
+			condp->path = tmp.envp;
+			condp++;
 		}
-		if (!condp)
-			e.condc++;
-		else
-			e.condc--;
-		if (left == CCS_EXEC_REALPATH) {
-			if (!names_p) {
-				e.names_count++;
-			} else {
-				e.names_count--;
-				right = CCS_NAME_UNION;
-				param->data = right_word;
-				if (!ccs_parse_name_union_quoted(param,
-								 names_p++))
-					goto out;
-			}
-			goto store_value;
+		if (tmp.right == CCS_IMM_GROUP) {
+			condp->group = tmp.group;
+			condp++;
+		} else if (tmp.right == CCS_IMM_NAME_ENTRY ||
+			   tmp.right == CCS_IMM_DOMAINNAME_ENTRY) {
+			condp->path = tmp.path;
+			condp++;
+		} else if (tmp.right == CCS_IMM_NUMBER_ENTRY1) {
+			condp->value = tmp.value[0];
+			condp++;
+		} else if (tmp.right == CCS_IMM_NUMBER_ENTRY2) {
+			condp->value = tmp.value[0];
+			condp++;
+			condp->value = tmp.value[1];
+			condp++;
+		} else if (tmp.right == CCS_IMM_IPV4ADDR_ENTRY1) {
+			condp->ip = * (u32 *) &tmp.ipv6[0];
+			condp++;
+		} else if (tmp.right == CCS_IMM_IPV4ADDR_ENTRY2) {
+			condp->ip = * (u32 *) &tmp.ipv6[0];
+			condp++;
+			condp->ip = * (u32 *) &tmp.ipv6[1];
+			condp++;
+		} else if (tmp.right == CCS_IMM_IPV6ADDR_ENTRY1) {
+			* (struct in6_addr *) condp = tmp.ipv6[0];
+			condp = (void *)
+				(((u8 *) condp) + sizeof(struct in6_addr));
+		} else if (tmp.right == CCS_IMM_IPV6ADDR_ENTRY2) {
+			* (struct in6_addr *) condp = tmp.ipv6[0];
+			condp = (void *)
+				(((u8 *) condp) + sizeof(struct in6_addr));
+			* (struct in6_addr *) condp = tmp.ipv6[1];
+			condp = (void *)
+				(((u8 *) condp) + sizeof(struct in6_addr));
 		}
-		right = ccs_condition_type(right_word);
-		if (right == CCS_MAX_CONDITION_KEYWORD) {
-			if (!numbers_p) {
-				e.numbers_count++;
-			} else {
-				e.numbers_count--;
-				right = CCS_NUMBER_UNION;
-				param->data = right_word;
-				if (!ccs_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 ccs_commit_condition(entry);
-	}
-	e.size = sizeof(*entry)
-		+ e.condc * sizeof(struct ccs_condition_element)
-		+ e.numbers_count * sizeof(struct ccs_number_union)
-		+ e.names_count * sizeof(struct ccs_name_union)
-		+ e.argc * sizeof(struct ccs_argv)
-		+ e.envc * sizeof(struct ccs_envp);
-	entry = kzalloc(e.size, CCS_GFP_FLAGS);
-	if (!entry)
-		return NULL;
-	*entry = e;
-	condp = (struct ccs_condition_element *) (entry + 1);
-	numbers_p = (struct ccs_number_union *) (condp + e.condc);
-	names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
-	argv = (struct ccs_argv *) (names_p + e.names_count);
-	envp = (struct ccs_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;
+	if (!handler_path_done)
+		goto out;
+	//if (!transit_domain_done)
+	//goto out;
+	entry->size = (void *) condp - (void *) entry;
+	//printk(KERN_WARNING "%u: committing %u\n", __LINE__, entry->size);
+	return ccs_commit_condition(entry);
 out:
+	// TODO: clean up tmp.
 	dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
 	if (entry) {
+		entry->size = (void *) condp - (void *) entry;
 		ccs_del_condition(&entry->head.list);
 		kfree(entry);
 	}
@@ -2280,74 +2564,25 @@
 }
 
 /**
- * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- *
- * Returns nothing.
- */
-static void ccs_set_slash(struct ccs_io_buffer *head)
-{
-	ccs_set_string(head, "/");
-}
-
-/**
- * ccs_init_policy_namespace - Initialize namespace.
- *
- * @ns: Pointer to "struct ccs_policy_namespace".
- *
- * Returns nothing.
- */
-static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
-{
-	unsigned int idx;
-	for (idx = 0; idx < CCS_MAX_GROUP; idx++)
-		INIT_LIST_HEAD(&ns->group_list[idx]);
-	INIT_LIST_HEAD(&ns->default_transition_list);
-	ns->profile_version = 20100903;
-	ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
-	list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list);
-}
-
-/**
- * ccs_print_namespace - Print namespace header.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- *
- * Returns nothing.
- */
-static void ccs_print_namespace(struct ccs_io_buffer *head)
-{
-	if (!ccs_namespace_enabled)
-		return;
-	ccs_set_string(head,
-		       container_of(head->r.ns, struct ccs_policy_namespace,
-				    namespace_list)->name);
-	ccs_set_space(head);
-}
-
-/**
  * ccs_assign_profile - Create a new profile.
  *
- * @ns:      Pointer to "struct ccs_policy_namespace".
  * @profile: Profile number to create.
  *
  * Returns pointer to "struct ccs_profile" on success, NULL otherwise.
  */
-static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
-					      const unsigned int profile)
+static struct ccs_profile *ccs_assign_profile(const unsigned int profile)
 {
 	struct ccs_profile *ptr;
 	struct ccs_profile *entry;
 	if (profile >= CCS_MAX_PROFILES)
 		return NULL;
-	ptr = ns->profile_ptr[profile];
+	ptr = ccs_profile_ptr[profile];
 	if (ptr)
 		return ptr;
 	entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
 	if (mutex_lock_interruptible(&ccs_policy_lock))
 		goto out;
-	ptr = ns->profile_ptr[profile];
+	ptr = ccs_profile_ptr[profile];
 	if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) {
 		ptr = entry;
 		ptr->default_config = CCS_CONFIG_DISABLED |
@@ -2359,7 +2594,7 @@
 		ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] =
 			CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY;
 		mb(); /* Avoid out-of-order execution. */
-		ns->profile_ptr[profile] = ptr;
+		ccs_profile_ptr[profile] = ptr;
 		entry = NULL;
 	}
 	mutex_unlock(&ccs_policy_lock);
@@ -2379,19 +2614,18 @@
 	const int idx = ccs_read_lock();
 	ccs_policy_loaded = true;
 	printk(KERN_INFO "CCSecurity: 1.8.3+   2011/12/13\n");
+	if (ccs_profile_version != 20100903) {
+		printk(KERN_ERR "Profile version %u is not supported.\n",
+		       ccs_profile_version);
+		goto out;
+	}
 	list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) {
 		const u8 profile = domain->profile;
-		const struct ccs_policy_namespace *ns = domain->ns;
-		if (ns->profile_version != 20100903)
-			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
+		if (ccs_profile_ptr[profile])
 			continue;
+		printk(KERN_ERR "Profile %u (used by '%s') is not defined.\n",
+		       profile, domain->domainname->name);
+out:
 		printk(KERN_ERR
 		       "Userland tools for TOMOYO 1.8 must be installed and "
 		       "policy must be initialized.\n");
@@ -2413,8 +2647,7 @@
 static struct ccs_profile *ccs_profile(const u8 profile)
 {
 	static struct ccs_profile ccs_null_profile;
-	struct ccs_profile *ptr = ccs_current_namespace()->
-		profile_ptr[profile];
+	struct ccs_profile *ptr = ccs_profile_ptr[profile];
 	if (!ptr)
 		ptr = &ccs_null_profile;
 	return ptr;
@@ -2509,46 +2742,6 @@
 }
 
 /**
- * ccs_group_type - Check whether the given string refers group or not.
- *
- * @src:  Pointer to pointer to the string.
- *
- * Returns 1 if @src refers a group in positive match, 2 if psrc refers a group
- * in negative match, 0 otherwise.
- *
- * The @src is updated to point the first character of a group name if @src
- * refers a group.
- */
-static u8 ccs_group_type(char **src)
-{
-	if (ccs_str_starts(src, "\\="))
-		return 1;
-	if (ccs_str_starts(src, "\\!"))
-		return 2;
-	return 0;
-}
-
-/**
- * ccs_print_group - Print group's name.
- *
- * @head:   Pointer to "struct ccs_io_buffer".
- * @is_not: True if @group is negative match, false otherwise.
- * @group:  Pointer to "struct ccsgroup". Maybe NULL.
- *
- * Returns true if @group is not NULL. false otherwise.
- */
-static bool ccs_print_group(struct ccs_io_buffer *head, const bool is_not,
-			    const struct ccs_group *group)
-{
-	if (group) {
-		ccs_set_string(head, is_not ? "\\!" : "\\=");
-		ccs_set_string(head, group->group_name->name);
-		return true;
-	}
-	return false;
-}
-
-/**
  * ccs_set_mode - Set mode for specified profile.
  *
  * @name:    Name of functionality.
@@ -2639,14 +2832,13 @@
 	unsigned int i;
 	char *cp;
 	struct ccs_profile *profile;
-	if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
-	    == 1)
+	if (sscanf(data, "PROFILE_VERSION=%u", &ccs_profile_version) == 1)
 		return 0;
 	i = simple_strtoul(data, &cp, 10);
 	if (*cp != '-')
 		return -EINVAL;
 	data = cp + 1;
-	profile = ccs_assign_profile(head->w.ns, i);
+	profile = ccs_assign_profile(i);
 	if (!profile)
 		return -EINVAL;
 	cp = strchr(data, '=');
@@ -2703,24 +2895,21 @@
 static void ccs_read_profile(struct ccs_io_buffer *head)
 {
 	u8 index;
-	struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
-						       namespace_list);
 	const struct ccs_profile *profile;
 	if (head->r.eof)
 		return;
 next:
 	index = head->r.index;
-	profile = ns->profile_ptr[index];
+	profile = ccs_profile_ptr[index];
 	switch (head->r.step) {
 	case 0:
-		ccs_print_namespace(head);
 		ccs_io_printf(head, "PROFILE_VERSION=%u\n",
-			      ns->profile_version);
+			      ccs_profile_version);
 		head->r.step++;
 		break;
 	case 1:
 		for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++)
-			if (ns->profile_ptr[head->r.index])
+			if (ccs_profile_ptr[head->r.index])
 				break;
 		if (head->r.index == CCS_MAX_PROFILES) {
 			head->r.eof = true;
@@ -2732,11 +2921,9 @@
 		{
 			u8 i;
 			const struct ccs_path_info *comment = profile->comment;
-			ccs_print_namespace(head);
 			ccs_io_printf(head, "%u-COMMENT=", index);
 			ccs_set_string(head, comment ? comment->name : "");
 			ccs_set_lf(head);
-			ccs_print_namespace(head);
 			ccs_io_printf(head, "%u-PREFERENCE={ ", index);
 			for (i = 0; i < CCS_MAX_PREF; i++)
 				ccs_io_printf(head, "%s=%u ",
@@ -2748,7 +2935,6 @@
 		break;
 	case 3:
 		{
-			ccs_print_namespace(head);
 			ccs_io_printf(head, "%u-%s", index, "CONFIG");
 			ccs_print_config(head, profile->default_config);
 			head->r.bit = 0;
@@ -2762,7 +2948,6 @@
 			const u8 config = profile->config[i];
 			if (config == CCS_CONFIG_USE_DEFAULT)
 				continue;
-			ccs_print_namespace(head);
 			if (i < CCS_MAX_MAC_INDEX)
 				ccs_io_printf(head, "%u-CONFIG::%s::%s", index,
 					      ccs_category_keywords
@@ -2837,7 +3022,6 @@
 				    const bool is_delete)
 {
 	struct ccs_acl_param param = {
-		/* .ns = &ccs_kernel_namespace, */
 		.is_delete = is_delete,
 		.list = &ccs_manager_list,
 	};
@@ -2845,14 +3029,10 @@
 	int error = is_delete ? -ENOENT : -ENOMEM;
 	/* Forced zero clear for using memcmp() at ccs_update_policy(). */
 	memset(&param.e, 0, sizeof(param.e));
-	if (ccs_domain_def(manager)) {
-		if (!ccs_correct_domain(manager))
-			return -EINVAL;
+	if (ccs_correct_domain(manager))
 		e->is_domain = true;
-	} else {
-		if (!ccs_correct_path(manager))
-			return -EINVAL;
-	}
+	else if (!ccs_correct_path(manager))
+		return -EINVAL;
 	e->manager = ccs_get_name(manager);
 	if (e->manager) {
 		error = ccs_update_policy(sizeof(*e), &param);
@@ -3054,10 +3234,8 @@
 	list_for_each_entry_srcu(entry, &ccs_inversed_acl_list, list,
 				 &ccs_ss) {
 		if (entry->is_deleted == CCS_GC_IN_PROGRESS ||
-		    entry->perm != new_entry->perm ||
 		    entry->type != new_entry->type ||
-		    entry->cond != new_entry->cond ||
-		    memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
+		    !entry->cond != !new_entry->cond)
 			continue;
 		entry->is_deleted = is_delete;
 		param->matched_entry = entry;
@@ -3068,7 +3246,7 @@
 	entry = ccs_commit_ok(new_entry, size);
 	if (!entry)
 		return -ENOMEM;
-	INIT_LIST_HEAD(&entry->domain_list);
+	INIT_LIST_HEAD(&entry->acl_info_list);
 	list_add_tail_rcu(&entry->list, &ccs_inversed_acl_list);
 	param->matched_entry = entry;
 	return 0;
@@ -3084,21 +3262,29 @@
  *
  * Caller holds ccs_read_lock().
  */
-static int ccs_update_acl(const int size, struct ccs_acl_param *param)
+static int ccs_update_acl(unsigned int size, struct ccs_acl_param *param)
 {
 	struct ccs_acl_info *new_entry = &param->e.acl_info;
 	const bool is_delete = param->is_delete;
 	int error = is_delete ? -ENOENT : -ENOMEM;
 	struct ccs_acl_info *entry;
 	struct list_head * const list = param->list;
+	if (!size)
+		size = sizeof(*entry);
 	BUG_ON(size < sizeof(*entry));
 	if (param->data[0]) {
+		char *line = kstrdup(param->data, CCS_GFP_FLAGS); 
 		new_entry->cond = ccs_get_condition(param);
 		if (!new_entry->cond)
+			printk(KERN_WARNING "%u: '%s' failed\n",
+			       __LINE__, line);
+		kfree(line);
+		if (!new_entry->cond)
 			return -EINVAL;
 	}
 	if (mutex_lock_interruptible(&ccs_policy_lock))
 		return -ENOMEM;
+	//printk(KERN_INFO "%s::list=%p\n", __func__, list);
 	if (!list) {
 		error = ccs_update_inverse_list(new_entry, size, param);
 		goto unlock;
@@ -3110,17 +3296,14 @@
 		    entry->cond != new_entry->cond ||
 		    memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
 			continue;
-		if (is_delete)
-			entry->perm &= ~new_entry->perm;
-		else
-			entry->perm |= new_entry->perm;
-		entry->is_deleted = !entry->perm;
+		entry->is_deleted = is_delete;
 		error = 0;
 		break;
 	}
 	if (error && !is_delete) {
 		entry = ccs_commit_ok(new_entry, size);
 		if (entry) {
+			INIT_LIST_HEAD(&entry->acl_info_list);
 			list_add_tail_rcu(&entry->list, list);
 			error = 0;
 		}
@@ -3131,323 +3314,40 @@
 }
 
 /**
- * ccs_permstr - Find permission keywords.
+ * ccs_parse_entry - Update ACL entry.
  *
- * @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.
- */
-static bool ccs_permstr(const char *string, const char *keyword)
-{
-	const char *cp = strstr(string, keyword);
-	if (cp)
-		return cp == string || *(cp - 1) == '/';
-	return false;
-}
-
-/**
- * ccs_write_task - Update task related list.
- *
  * @param: Pointer to "struct ccs_acl_param".
  *
  * Returns 0 on success, negative value otherwise.
  *
  * Caller holds ccs_read_lock().
  */
-static int ccs_write_task(struct ccs_acl_param *param)
+static int ccs_parse_entry(struct ccs_acl_param *param)
 {
-	int error;
-	const bool is_auto = ccs_str_starts(&param->data,
-					    "auto_domain_transition ");
-	if (!is_auto && !ccs_str_starts(&param->data,
-					"manual_domain_transition ")) {
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-		struct ccs_handler_acl *e = &param->e.handler_acl;
-		char *handler;
-		if (ccs_str_starts(&param->data, "auto_execute_handler "))
-			e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
-		else if (ccs_str_starts(&param->data,
-					"denied_execute_handler "))
-			e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
-		else
-			return -EINVAL;
-		handler = ccs_read_token(param);
-		if (!ccs_correct_path(handler))
-			return -EINVAL;
-		e->handler = ccs_get_name(handler);
-		if (!e->handler)
-			return -ENOMEM;
-		if (e->handler->is_patterned)
-			return -EINVAL; /* No patterns allowed. */
-		return ccs_update_acl(sizeof(*e), param);
-#else
-		error = -EINVAL;
-#endif
-	} else {
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-		struct ccs_task_acl *e = &param->e.task_acl;
-		e->head.type = is_auto ?
-			CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL;
-		e->domainname = ccs_get_domainname(param);
-		if (!e->domainname)
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-#else
-		error = -EINVAL;
-#endif
-	}
-	return error;
-}
-
-#ifdef CONFIG_CCSECURITY_NETWORK
-
-/**
- * ccs_write_inet_network - Write "struct ccs_inet_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static int ccs_write_inet_network(struct ccs_acl_param *param)
-{
-	struct ccs_inet_acl *e = &param->e.inet_acl;
-	u8 type;
-	const char *protocol = ccs_read_token(param);
+	enum ccs_mac_index type;
+	const char *category = ccs_read_token(param);
 	const char *operation = ccs_read_token(param);
-	e->head.type = CCS_TYPE_INET_ACL;
-	for (type = 0; type < CCS_SOCK_MAX; type++)
-		if (!strcmp(protocol, ccs_proto_keyword[type]))
-			break;
-	if (type == CCS_SOCK_MAX)
-		return -EINVAL;
-	e->protocol = type;
-	e->head.perm = 0;
-	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_socket_keyword[type]))
-			e->head.perm |= 1 << type;
-	if (!e->head.perm)
-		return -EINVAL;
-	if (!ccs_parse_ipaddr_union(param, &e->address))
-		return -EINVAL;
-	if (!ccs_parse_number_union(param, &e->port) ||
-	    e->port.values[1] > 65535)
-		return -EINVAL;
-	return ccs_update_acl(sizeof(*e), param);
-}
-
-/**
- * ccs_write_unix_network - Write "struct ccs_unix_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_unix_network(struct ccs_acl_param *param)
-{
-	struct ccs_unix_acl *e = &param->e.unix_acl;
-	u8 type;
-	const char *protocol = ccs_read_token(param);
-	const char *operation = ccs_read_token(param);
-	e->head.type = CCS_TYPE_UNIX_ACL;
-	for (type = 0; type < CCS_SOCK_MAX; type++)
-		if (!strcmp(protocol, ccs_proto_keyword[type]))
-			break;
-	if (type == CCS_SOCK_MAX)
-		return -EINVAL;
-	e->protocol = type;
-	e->head.perm = 0;
-	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_socket_keyword[type]))
-			e->head.perm |= 1 << type;
-	if (!e->head.perm)
-		return -EINVAL;
-	if (!ccs_parse_name_union(param, &e->name))
-		return -EINVAL;
-	return ccs_update_acl(sizeof(*e), param);
-}
-
-#endif
-
-/**
- * ccs_update_execute_acl - Update execute entry.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static int ccs_update_execute_acl(struct ccs_acl_param *param)
-{
-	struct ccs_execute_acl *e = &param->e.execute_acl;
-	e->head.type = CCS_TYPE_EXECUTE_ACL;
-	e->head.perm = 1;
-	if (!ccs_parse_name_union(param, &e->program))
-		return -EINVAL;
-	param->data = ccs_get_transit_preference(param, e);
-	if (!param->data)
-		return -EINVAL;
-	return ccs_update_acl(sizeof(*e), param);
-}
-
-/**
- * ccs_write_file - Update file related list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static int ccs_write_file(struct ccs_acl_param *param)
-{
-	u16 perm = 0;
-	u8 type;
-	const char *operation = ccs_read_token(param);
-	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_EXECUTE]))
-		return ccs_update_execute_acl(param);
-	for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_mac_keywords[ccs_p2mac[type]]))
-			perm |= 1 << type;
-	if (perm) {
-		struct ccs_path_acl *e = &param->e.path_acl;
-		e->head.type = CCS_TYPE_PATH_ACL;
-		e->head.perm = perm;
-		if (!ccs_parse_name_union(param, &e->name))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]]))
-			perm |= 1 << type;
-	if (perm) {
-		struct ccs_path2_acl *e = &param->e.path2_acl;
-		e->head.type = CCS_TYPE_PATH2_ACL;
-		e->head.perm = perm;
-		if (!ccs_parse_name_union(param, &e->name1) ||
-		    !ccs_parse_name_union(param, &e->name2))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]]))
-			perm |= 1 << type;
-	if (perm) {
-		struct ccs_path_number_acl *e = &param->e.path_number_acl;
-		e->head.type = CCS_TYPE_PATH_NUMBER_ACL;
-		e->head.perm = perm;
-		if (!ccs_parse_name_union(param, &e->name) ||
-		    !ccs_parse_number_union(param, &e->number))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++)
-		if (ccs_permstr(operation,
-				ccs_mac_keywords[ccs_pnnn2mac[type]]))
-			perm |= 1 << type;
-	if (perm) {
-		struct ccs_mkdev_acl *e = &param->e.mkdev_acl;
-		e->head.type = CCS_TYPE_MKDEV_ACL;
-		e->head.perm = perm;
-		if (!ccs_parse_name_union(param, &e->name) ||
-		    !ccs_parse_number_union(param, &e->mode) ||
-		    !ccs_parse_number_union(param, &e->major) ||
-		    !ccs_parse_number_union(param, &e->minor))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) {
-		struct ccs_mount_acl *e = &param->e.mount_acl;
-		e->head.type = CCS_TYPE_MOUNT_ACL;
-		if (!ccs_parse_name_union(param, &e->dev_name) ||
-		    !ccs_parse_name_union(param, &e->dir_name) ||
-		    !ccs_parse_name_union(param, &e->fs_type) ||
-		    !ccs_parse_number_union(param, &e->flags))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	return -EINVAL;
-}
-
-#ifdef CONFIG_CCSECURITY_MISC
-
-/**
- * ccs_write_misc - Update environment variable list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_misc(struct ccs_acl_param *param)
-{
-	if (ccs_str_starts(&param->data, "env ")) {
-		struct ccs_env_acl *e = &param->e.env_acl;
-		e->head.type = CCS_TYPE_ENV_ACL;
-		if (!ccs_parse_name_union(param, &e->env))
-			return -EINVAL;
-		return ccs_update_acl(sizeof(*e), param);
-	}
-	return -EINVAL;
-}
-
-#endif
-
-#ifdef CONFIG_CCSECURITY_IPC
-
-/**
- * ccs_write_ipc - Update "struct ccs_ptrace_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_ipc(struct ccs_acl_param *param)
-{
-	struct ccs_ptrace_acl *e = &param->e.ptrace_acl;
-	e->head.type = CCS_TYPE_PTRACE_ACL;
-	if (!ccs_parse_number_union(param, &e->request))
-		return -EINVAL;
-	e->domainname = ccs_get_domainname(param);
-	if (!e->domainname)
-		return -EINVAL;
-	return ccs_update_acl(sizeof(*e), param);
-}
-
-#endif
-
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-
-/**
- * ccs_write_capability - Write "struct ccs_capability_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static int ccs_write_capability(struct ccs_acl_param *param)
-{
-	struct ccs_capability_acl *e = &param->e.capability_acl;
-	const char *operation = ccs_read_token(param);
-	u8 type;
-	e->head.type = CCS_TYPE_CAPABILITY_ACL;
-	for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) {
-		if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]]))
+	for (type = CCS_MAC_FILE_EXECUTE; type < CCS_MAX_MAC_INDEX; type++) {
+		if (!ccs_category_keywords[ccs_index2category[type]]) {
+			printk(KERN_INFO
+			       "ccs_category_keywords[ccs_index2category[%u]]"
+			       "==NULL\n", type);
 			continue;
-		e->operation = type;
-		return ccs_update_acl(sizeof(*e), param);
+		}
+		if (!ccs_mac_keywords[type]) {
+			printk(KERN_INFO "ccs_mac_keywords[%u]==NULL\n", type);
+			continue;
+		}
+		if (strcmp(category, ccs_category_keywords
+			   [ccs_index2category[type]]) ||
+		    strcmp(operation, ccs_mac_keywords[type]))
+			continue;
+		param->e.acl_info.type = type;
+		return ccs_update_acl(0, param);
 	}
 	return -EINVAL;
 }
 
-#endif
-
 /**
  * ccs_write_use_group_acl - Write "struct ccs_use_group_acl" list.
  *
@@ -3460,23 +3360,16 @@
 static int ccs_write_use_group_acl(struct ccs_acl_param *param)
 {
 	struct ccs_use_group_acl *e = &param->e.use_group_acl;
-	e->head.type = CCS_TYPE_USE_GROUP_ACL;
-	switch (ccs_group_type(&param->data)) {
-	case 2:
-		e->is_not = true;
-		/* fall through */
-	case 1:
-		e->group = ccs_get_group(param, CCS_ACL_GROUP);
-		if (e->group)
-			return ccs_update_acl(sizeof(*e), param);
-	}
+	e->head.type = CCS_MAC_USE_GROUP;
+	e->group = ccs_get_group(param, CCS_ACL_GROUP);
+	if (e->group)
+		return ccs_update_acl(sizeof(*e), param);
 	return -EINVAL;
 }
 
 /**
  * ccs_write_acl - Write "struct ccs_acl_info" list.
  *
- * @ns:        Pointer to "struct ccs_policy_namespace".
  * @list:      Pointer to "struct list_head".
  * @data:      Policy to be interpreted.
  * @is_delete: True if it is a delete request.
@@ -3485,12 +3378,10 @@
  *
  * Caller holds ccs_read_lock().
  */
-static int ccs_write_acl(struct ccs_policy_namespace *ns,
-			 struct list_head *list, char *data,
+static int ccs_write_acl(struct list_head *list, char *data,
 			 const bool is_delete)
 {
 	struct ccs_acl_param param = {
-		.ns = ns,
 		.list = list,
 		.data = data,
 		.is_delete = is_delete,
@@ -3499,27 +3390,12 @@
 		const char *keyword;
 		int (*write) (struct ccs_acl_param *);
 	} ccs_callback[] = {
-		{ "file ", ccs_write_file },
-#ifdef CONFIG_CCSECURITY_NETWORK
-		{ "network inet ", ccs_write_inet_network },
-		{ "network unix ", ccs_write_unix_network },
-#endif
-#ifdef CONFIG_CCSECURITY_MISC
-		{ "misc ", ccs_write_misc },
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-		{ "capability ", ccs_write_capability },
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-		{ "ipc ptrace ", ccs_write_ipc },
-#endif
-		{ "task ", ccs_write_task },
 		{ "use_group ", ccs_write_use_group_acl },
+		{ "", ccs_parse_entry }
 	};
 	u8 i;
 	/* Forced zero clear for using memcmp() at ccs_update_acl(). */
 	memset(&param.e, 0, sizeof(param.e));
-	param.e.acl_info.perm = 1;
 	for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
 		int error;
 		if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
@@ -3573,7 +3449,6 @@
 static int ccs_write_domain(struct ccs_io_buffer *head)
 {
 	char *data = head->write_buf;
-	struct ccs_policy_namespace *ns;
 	struct ccs_domain_info *domain = head->w.domain;
 	const bool is_delete = head->w.is_delete;
 	const bool is_select = !is_delete && ccs_str_starts(&data, "select ");
@@ -3591,10 +3466,9 @@
 	}
 	if (!domain)
 		return -EINVAL;
-	ns = domain->ns;
 	if (sscanf(data, "use_profile %u\n", &profile) == 1
 	    && profile < CCS_MAX_PROFILES) {
-		if (!ccs_policy_loaded || ns->profile_ptr[(u8) profile])
+		if (!ccs_policy_loaded || ccs_profile_ptr[(u8) profile])
 			if (!is_delete)
 				domain->profile = (u8) profile;
 		return 0;
@@ -3622,231 +3496,248 @@
 		domain->quota_exceeded = !is_delete;
 		return 0;
 	}
-	return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete);
+	return ccs_write_acl(&domain->acl_info_list, data, is_delete);
 }
 
-/**
- * ccs_print_name_union - Print a ccs_name_union.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- * @ptr:  Pointer to "struct ccs_name_union".
- *
- * Returns nothing.
- */
-static void ccs_print_name_union(struct ccs_io_buffer *head,
-				 const struct ccs_name_union *ptr)
+static void ccs_print_number(struct ccs_io_buffer *head, const u8 radix,
+			     const unsigned long value)
 {
-	ccs_set_space(head);
-	if (!ccs_print_group(head, ptr->is_not, ptr->group))
-		ccs_set_string(head, ptr->filename->name);
+	switch (radix) {
+	case CCS_VALUE_TYPE_HEXADECIMAL:
+		ccs_io_printf(head, "0x%lX", value);
+		break;
+	case CCS_VALUE_TYPE_OCTAL:
+		ccs_io_printf(head, "0%lo", value);
+		break;
+	default:
+		ccs_io_printf(head, "%lu", value);
+	}
 }
 
-/**
- * ccs_print_name_union_quoted - Print a ccs_name_union with a quote.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- * @ptr:  Pointer to "struct ccs_name_union".
- *
- * Returns nothing.
- */
-static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
-					const struct ccs_name_union *ptr)
+static void ccs_print_misc_attribute(struct ccs_io_buffer *head,
+				     const enum ccs_mac_index type,
+				     const enum ccs_conditions_index cond)
 {
-	if (!ccs_print_group(head, ptr->is_not, ptr->group)) {
-		ccs_set_string(head, "\"");
-		ccs_set_string(head, ptr->filename->name);
-		ccs_set_string(head, "\"");
+	static const char *const k[CCS_MAX_PATH_ATTRIBUTE] = {
+		[CCS_PATH_ATTRIBUTE_UID]       = "uid",
+		[CCS_PATH_ATTRIBUTE_GID]       = "gid",
+		[CCS_PATH_ATTRIBUTE_INO]       = "ino",
+		[CCS_PATH_ATTRIBUTE_MAJOR]     = "major",
+		[CCS_PATH_ATTRIBUTE_MINOR]     = "minor",
+		[CCS_PATH_ATTRIBUTE_PERM]      = "perm",
+		[CCS_PATH_ATTRIBUTE_TYPE]      = "type",
+		[CCS_PATH_ATTRIBUTE_DEV_MAJOR] = "dev_major",
+		[CCS_PATH_ATTRIBUTE_DEV_MINOR] = "dev_minor",
+	};
+	if (cond >= CCS_PATH_ATTRIBUTE_START) {
+		const u8 pos = cond - CCS_PATH_ATTRIBUTE_START;
+		ccs_io_printf(head, "%s.%s%s", ccs_get_sarg(type, pos >= 32),
+			      pos % 32 >= 16 ? "parent." : "", k[pos % 16]);
+		return;
 	}
+	switch (cond) {
+	case CCS_SELF_UID:
+	case CCS_SELF_EUID:
+	case CCS_SELF_SUID:
+	case CCS_SELF_FSUID:
+	case CCS_SELF_GID:
+	case CCS_SELF_EGID:
+	case CCS_SELF_SGID:
+	case CCS_SELF_FSGID:
+	case CCS_SELF_PID:
+	case CCS_SELF_PPID:
+	case CCS_TASK_TYPE:
+	case CCS_SELF_DOMAIN:
+		ccs_set_string(head, "task.");
+		/* fall through */
+	default:
+		if (cond < CCS_MAX_CONDITION_KEYWORD)
+			ccs_set_string(head, ccs_condition_keyword[cond]);
+		else
+			ccs_io_printf(head, "unknown(%u)", cond);
+	}
 }
 
+static void ccs_print_ipv4_address(struct ccs_io_buffer *head,
+				   const u32 *ip)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+	ccs_io_printf(head, "%pI4", ip);
+#else
+	char addr[sizeof("255.255.255.255")];
+	ip4_string(addr, (const u8 *) ip);
+	ccs_io_printf(head, "%s", addr);
+#endif
+}
+
+static void ccs_print_ipv6_address(struct ccs_io_buffer *head,
+				   const struct in6_addr *ip)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+	ccs_io_printf(head, "%pI6c", ip);
+#else
+	char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:"
+			 "255.255.255.255")];
+	ip6_compressed_string(addr, (const u8 *) ip);
+	ccs_io_printf(head, "%s", addr);
+#endif
+}
+
 /**
- * ccs_print_number_union_nospace - Print a ccs_number_union without a space.
+ * ccs_print_condition_loop - Print condition part.
  *
  * @head: Pointer to "struct ccs_io_buffer".
- * @ptr:  Pointer to "struct ccs_number_union".
+ * @type: One of values in "enum ccs_mac_index".
+ * @cond: Pointer to "struct ccs_condition".
  *
- * Returns nothing.
+ * Returns true on success, false otherwise.
  */
-static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
-					   const struct ccs_number_union *ptr)
+static bool ccs_print_condition_loop(struct ccs_io_buffer *head,
+				     const enum ccs_mac_index type,
+				     const struct ccs_condition *cond)
 {
-	if (!ccs_print_group(head, ptr->is_not, ptr->group)) {
-		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 CCS_VALUE_TYPE_HEXADECIMAL:
-				ccs_addprintf(buffer, sizeof(buffer), "0x%lX",
-					      min);
+	const union ccs_condition_element *condp = head->r.cond;
+	while ((void *) condp < (void *) ((u8 *) cond) + cond->size) {
+		const bool match = condp->equals;
+		const enum ccs_conditions_index left = condp->left;
+		const enum ccs_conditions_index right = condp->right;
+		const u8 radix = condp->radix;
+		if (!ccs_flush(head)) {
+			head->r.cond = condp;
+			return false;
+		}
+		condp++;
+		ccs_set_space(head);
+		switch (left) {
+		case CCS_ARGV_ENTRY:
+			ccs_io_printf(head, "argv[%lu]", condp->value);
+			condp++;
+			break;
+		case CCS_ENVP_ENTRY:
+			ccs_set_string(head, "envp[\"");
+			ccs_set_string(head, condp->path->name);
+			condp++;
+			ccs_set_string(head, "\"]");
+			break;
+		case CCS_COND_SARG0:
+			ccs_set_string(head, ccs_get_sarg(type, 0));
+			break;
+		case CCS_COND_SARG1:
+			ccs_set_string(head, ccs_get_sarg(type, 1));
+			break;
+		case CCS_COND_SARG2:
+			ccs_set_string(head, ccs_get_sarg(type, 2));
+			break;
+		case CCS_COND_NARG0:
+			ccs_set_string(head, ccs_get_narg(type, 0));
+			break;
+		case CCS_COND_NARG1:
+			ccs_set_string(head, ccs_get_narg(type, 1));
+			break;
+		case CCS_COND_NARG2:
+			ccs_set_string(head, ccs_get_narg(type, 2));
+			break;
+		case CCS_COND_IPARG:
+			ccs_set_string(head, "ip");
+			break;
+		default:
+			ccs_print_misc_attribute(head, type, left);
+		}
+		ccs_set_string(head, match ? "=" : "!=");
+		switch (right) {
+		case CCS_IMM_GROUP:
+			ccs_set_string(head, "@");
+			ccs_set_string(head, condp->group->group_name->name);
+			condp++;
+			break;
+		case CCS_IMM_NAME_ENTRY:
+			if (condp->path) {
+				ccs_set_string(head, "\"");
+				ccs_set_string(head, condp->path->name);
+				ccs_set_string(head, "\"");
+			} else {
+				ccs_set_string(head, "NULL");
+			}
+			condp++;
+			break;
+		case CCS_IMM_DOMAINNAME_ENTRY:
+			ccs_set_string(head, condp->path->name);
+			condp++;
+			break;
+		case CCS_IMM_NUMBER_ENTRY1:
+		case CCS_IMM_NUMBER_ENTRY2:
+			ccs_print_number(head, radix & 3, condp->value);
+			condp++;
+			if (right == CCS_IMM_NUMBER_ENTRY1)
 				break;
-			case CCS_VALUE_TYPE_OCTAL:
-				ccs_addprintf(buffer, sizeof(buffer), "0%lo",
-					      min);
+			ccs_set_string(head, "-");
+			ccs_print_number(head, (radix >> 2) & 3, condp->value);
+			condp++;
+			break;
+		case CCS_IMM_IPV4ADDR_ENTRY1:
+		case CCS_IMM_IPV4ADDR_ENTRY2:
+			ccs_print_ipv4_address(head, &condp->ip);
+			condp++;
+			if (right == CCS_IMM_IPV4ADDR_ENTRY1)
 				break;
-			default:
-				ccs_addprintf(buffer, sizeof(buffer), "%lu",
-					      min);
+			ccs_set_string(head, "-");
+			ccs_print_ipv4_address(head, &condp->ip);
+			condp++;
+			break;
+		case CCS_IMM_IPV6ADDR_ENTRY1:
+		case CCS_IMM_IPV6ADDR_ENTRY2:
+			ccs_print_ipv6_address(head, (const struct in6_addr *)
+					       condp);
+			condp = (void *)
+				((u8 *) condp) + sizeof(struct in6_addr);
+			if (right == CCS_IMM_IPV6ADDR_ENTRY1)
 				break;
-			}
-			if (min == max && min_type == max_type)
-				break;
-			ccs_addprintf(buffer, sizeof(buffer), "-");
-			min_type = max_type;
-			min = max;
+			ccs_set_string(head, "-");
+			ccs_print_ipv6_address(head, (const struct in6_addr *)
+					       condp);
+			condp = (void *)
+				((u8 *) condp) + sizeof(struct in6_addr);
+			break;
+		default:
+			ccs_print_misc_attribute(head, type, right);
 		}
-		ccs_io_printf(head, "%s", buffer);
 	}
+	head->r.cond = NULL;
+	return true;
 }
 
 /**
- * ccs_print_number_union - Print a ccs_number_union.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- * @ptr:  Pointer to "struct ccs_number_union".
- *
- * Returns nothing.
- */
-static void ccs_print_number_union(struct ccs_io_buffer *head,
-				   const struct ccs_number_union *ptr)
-{
-	ccs_set_space(head);
-	ccs_print_number_union_nospace(head, ptr);
-}
-
-/**
  * ccs_print_condition - Print condition part.
  *
  * @head: Pointer to "struct ccs_io_buffer".
+ * @type: One of values in "enum ccs_mac_index".
  * @cond: Pointer to "struct ccs_condition".
  *
  * Returns true on success, false otherwise.
  */
 static bool ccs_print_condition(struct ccs_io_buffer *head,
+				const enum ccs_mac_index type,
 				const struct ccs_condition *cond)
 {
 	switch (head->r.cond_step) {
 	case 0:
-		head->r.cond_index = 0;
+		//printk(KERN_INFO "Enter %s 0\n", __func__);
+		head->r.cond = (const union ccs_condition_element *)
+			(cond + 1);
 		head->r.cond_step++;
 		/* fall through */
 	case 1:
-		{
-			const u16 condc = cond->condc;
-			const struct ccs_condition_element *condp =
-				(typeof(condp)) (cond + 1);
-			const struct ccs_number_union *numbers_p =
-				(typeof(numbers_p)) (condp + condc);
-			const struct ccs_name_union *names_p =
-				(typeof(names_p))
-				(numbers_p + cond->numbers_count);
-			const struct ccs_argv *argv =
-				(typeof(argv)) (names_p + cond->names_count);
-			const struct ccs_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 CCS_ARGV_ENTRY:
-					argv++;
-					continue;
-				case CCS_ENVP_ENTRY:
-					envp++;
-					continue;
-				case CCS_NUMBER_UNION:
-					numbers_p++;
-					break;
-				}
-				switch (right) {
-				case CCS_NAME_UNION:
-					names_p++;
-					break;
-				case CCS_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 (!ccs_flush(head))
-					return false;
-				condp++;
-				head->r.cond_index++;
-				ccs_set_space(head);
-				switch (left) {
-				case CCS_ARGV_ENTRY:
-					ccs_io_printf(head,
-						      "exec.argv[%lu]%s=\"",
-						      argv->index,
-						      argv->is_not ? "!" : "");
-					ccs_set_string(head,
-						       argv->value->name);
-					ccs_set_string(head, "\"");
-					argv++;
-					continue;
-				case CCS_ENVP_ENTRY:
-					ccs_set_string(head, "exec.envp[\"");
-					ccs_set_string(head, envp->name->name);
-					ccs_io_printf(head, "\"]%s=",
-						      envp->is_not ? "!" : "");
-					if (envp->value) {
-						ccs_set_string(head, "\"");
-						ccs_set_string(head, envp->
-							       value->name);
-						ccs_set_string(head, "\"");
-					} else {
-						ccs_set_string(head, "NULL");
-					}
-					envp++;
-					continue;
-				case CCS_NUMBER_UNION:
-					ccs_print_number_union_nospace
-						(head, numbers_p++);
-					break;
-				default:
-					ccs_set_string(head,
-					       ccs_condition_keyword[left]);
-					break;
-				}
-				ccs_set_string(head, match ? "=" : "!=");
-				switch (right) {
-				case CCS_NAME_UNION:
-					ccs_print_name_union_quoted
-						(head, names_p++);
-					break;
-				case CCS_NUMBER_UNION:
-					ccs_print_number_union_nospace
-						(head, numbers_p++);
-					break;
-				default:
-					ccs_set_string(head,
-					       ccs_condition_keyword[right]);
-					break;
-				}
-			}
-		}
+		//printk(KERN_INFO "Enter %s 1\n", __func__);
+		if (!ccs_print_condition_loop(head, type, cond))
+			return false;
 		head->r.cond_step++;
 		/* fall through */
 	case 2:
-		if (!ccs_flush(head))
-			break;
-		head->r.cond_step++;
-		/* fall through */
-	case 3:
-		if (cond->grant_log != CCS_GRANTLOG_AUTO)
-			ccs_io_printf(head, " grant_log=%s",
-				      ccs_yesno(cond->grant_log ==
-						CCS_GRANTLOG_YES));
-		ccs_set_lf(head);
+		//printk(KERN_INFO "Enter %s 2\n", __func__);
+		//if (!ccs_flush(head))
+		//break;
+		//ccs_set_lf(head);
+		head->r.cond = NULL;
 		return true;
 	}
 	return false;
@@ -3863,12 +3754,11 @@
 static void ccs_set_group(struct ccs_io_buffer *head, const char *category)
 {
 	if (head->type == CCS_EXCEPTION_POLICY) {
-		ccs_print_namespace(head);
 		ccs_set_string(head, "acl_group ");
 		ccs_set_string(head, head->r.acl_group_name->name);
 		ccs_set_space(head);
 	} else if (head->type == CCS_ACL_POLICY) {
-		ccs_set_string(head, "allow ");
+		ccs_set_string(head, "acl ");
 	}
 	ccs_set_string(head, category);
 }
@@ -3884,237 +3774,47 @@
 static bool ccs_print_entry(struct ccs_io_buffer *head,
 			    const struct ccs_acl_info *acl)
 {
-	const u8 acl_type = acl->type;
-	bool first = true;
-	u8 bit;
-	if (head->r.print_cond_part)
+	const enum ccs_mac_index acl_type = acl->type;
+	//printk(KERN_INFO "Enter %s 0\n", __func__);
+	if (head->r.cond)
 		goto print_cond_part;
 	if (acl->is_deleted)
 		return true;
+	BUG_ON(head->r.print_default_transition &&
+	       acl_type != CCS_MAC_FILE_EXECUTE);
 	if (!ccs_flush(head))
 		return false;
 	/*
 	if (head->type == CCS_EXCEPTION_POLICY && head->r.acl_group_name)
 		printk(KERN_INFO "%s ptr=%p\n", __func__, acl);
 	*/
-	else if (acl_type == CCS_TYPE_EXECUTE_ACL) {
-		struct ccs_execute_acl *ptr
-			= container_of(acl, typeof(*ptr), head);
+	else if (acl_type == CCS_MAC_FILE_EXECUTE) {
 		if (head->r.print_default_transition) {
-			ccs_print_namespace(head);
 			ccs_set_string(head, "default_transition");
 		} else {
 			ccs_set_group(head, "file ");
 			ccs_set_string(head, "execute");
 		}
-		ccs_print_name_union(head, &ptr->program);
-		if (ptr->transit) {
-			ccs_set_space(head);
-			ccs_set_string(head, ptr->transit->name);
-		}
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-	} else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
-		   acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
-		struct ccs_handler_acl *ptr
-			= container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "task ");
-		ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
-			       ? "auto_execute_handler " :
-			       "denied_execute_handler ");
-		ccs_set_string(head, ptr->handler->name);
-		if (ptr->transit) {
-			ccs_set_space(head);
-			ccs_set_string(head, ptr->transit->name);
-		}
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-	} else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
-		   acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
-		struct ccs_task_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "task ");
-		ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ?
-			       "auto_domain_transition " :
-			       "manual_domain_transition ");
-		ccs_set_string(head, ptr->domainname->name);
-#endif
-	} else if (acl_type == CCS_TYPE_USE_GROUP_ACL) {
+	} else if (acl_type == CCS_MAC_USE_GROUP) {
 		struct ccs_use_group_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
 		ccs_set_group(head, "use_group ");
-		ccs_print_group(head, ptr->is_not, ptr->group);
+		ccs_set_string(head, ptr->group->group_name->name);
 	} else if (head->r.print_transition_related_only) {
 		return true;
-	} else if (acl_type == CCS_TYPE_PATH_ACL) {
-		struct ccs_path_acl *ptr
-			= container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "file ");
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_mac_keywords[ccs_p2mac[bit]]);
-		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name);
-	} else if (acl_type == CCS_TYPE_MKDEV_ACL) {
-		struct ccs_mkdev_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "file ");
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_mac_keywords
-				       [ccs_pnnn2mac[bit]]);
-		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name);
-		ccs_print_number_union(head, &ptr->mode);
-		ccs_print_number_union(head, &ptr->major);
-		ccs_print_number_union(head, &ptr->minor);
-	} else if (acl_type == CCS_TYPE_PATH2_ACL) {
-		struct ccs_path2_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "file ");
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_mac_keywords
-				       [ccs_pp2mac[bit]]);
-		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name1);
-		ccs_print_name_union(head, &ptr->name2);
-	} else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
-		struct ccs_path_number_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "file ");
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_mac_keywords
-				       [ccs_pn2mac[bit]]);
-		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name);
-		ccs_print_number_union(head, &ptr->number);
-#ifdef CONFIG_CCSECURITY_MISC
-	} else if (acl_type == CCS_TYPE_ENV_ACL) {
-		struct ccs_env_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "misc env");
-		ccs_print_name_union(head, &ptr->env);
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-	} else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
-		struct ccs_capability_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "capability ");
-		ccs_set_string(head, ccs_mac_keywords
-			       [ccs_c2mac[ptr->operation]]);
-#endif
-#ifdef CONFIG_CCSECURITY_NETWORK
-	} else if (acl_type == CCS_TYPE_INET_ACL) {
-		struct ccs_inet_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "network inet ");
-				ccs_set_string(head, ccs_proto_keyword
-					       [ptr->protocol]);
-				ccs_set_space(head);
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_socket_keyword[bit]);
-		}
-		if (first)
-			return true;
+	} else if (acl_type < CCS_MAX_MAC_INDEX) {
+		ccs_set_group(head, ccs_category_keywords
+			      [ccs_index2category[acl_type]]);
 		ccs_set_space(head);
-		if (!ccs_print_group(head, ptr->address.is_not,
-				     ptr->address.group)) {
-			char buf[128];
-			ccs_print_ip(buf, sizeof(buf), &ptr->address);
-			ccs_io_printf(head, "%s", buf);
-		}
-		ccs_print_number_union(head, &ptr->port);
-	} else if (acl_type == CCS_TYPE_UNIX_ACL) {
-		struct ccs_unix_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (first) {
-				ccs_set_group(head, "network unix ");
-				ccs_set_string(head, ccs_proto_keyword
-					       [ptr->protocol]);
-				ccs_set_space(head);
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_socket_keyword[bit]);
-		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name);
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-	} else if (acl_type == CCS_TYPE_PTRACE_ACL) {
-		struct ccs_ptrace_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "ipc ptrace ");
-		ccs_print_number_union_nospace(head, &ptr->request);
-		ccs_set_space(head);
-		ccs_set_string(head, ptr->domainname->name);
-#endif
-	} else if (acl_type == CCS_TYPE_MOUNT_ACL) {
-		struct ccs_mount_acl *ptr =
-			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "file mount");
-		ccs_print_name_union(head, &ptr->dev_name);
-		ccs_print_name_union(head, &ptr->dir_name);
-		ccs_print_name_union(head, &ptr->fs_type);
-		ccs_print_number_union(head, &ptr->flags);
+		ccs_set_string(head, ccs_mac_keywords[acl_type]);
 	}
 	if (acl->cond) {
-		head->r.print_cond_part = true;
 		head->r.cond_step = 0;
-		if (!ccs_flush(head))
-			return false;
 print_cond_part:
-		if (!ccs_print_condition(head, acl->cond))
+		if (!ccs_print_condition(head, acl_type, acl->cond))
 			return false;
-		head->r.print_cond_part = false;
-	} else {
-		ccs_set_lf(head);
 	}
+	ccs_set_lf(head);
 	return true;
 }
 
@@ -4277,9 +3977,9 @@
 {
 	int error = -EINVAL;
 	struct ccs_group *group = ccs_get_group(param, type);
-	if (!group || group == &ccs_group_any)
+	if (!group)
 		return -ENOMEM;
-	if (type != CCS_ACL_GROUP && ccs_group_type(&param->data))
+	if (type != CCS_ACL_GROUP && ccs_str_starts(&param->data, "@"))
 		goto out;
 	param->list = &group->member_list;
 	if (type == CCS_PATH_GROUP) {
@@ -4293,10 +3993,12 @@
 		ccs_put_name(e->member_name);
 	} else if (type == CCS_NUMBER_GROUP) {
 		struct ccs_number_group *e = &param->e.number_group;
-		if (ccs_parse_number_union(param, &e->number))
-			error = ccs_update_policy(sizeof(*e), param);
+		e->radix = ccs_parse_values(ccs_read_token(param), e->value);
+		if (e->radix == CCS_VALUE_TYPE_INVALID)
+			goto out;
+		error = ccs_update_policy(sizeof(*e), param);
 	} else if (type == CCS_ACL_GROUP) {
-		error = ccs_write_acl(param->ns, param->list, param->data,
+		error = ccs_write_acl(param->list, param->data,
 				      param->is_delete);
 		/*
 		printk(KERN_INFO "%s: ptr=%p ret=%d\n", __func__, group,
@@ -4305,8 +4007,19 @@
 #ifdef CONFIG_CCSECURITY_NETWORK
 	} else {
 		struct ccs_address_group *e = &param->e.address_group;
-		if (ccs_parse_ipaddr_union(param, &e->address))
-			error = ccs_update_policy(sizeof(*e), param);
+		switch (ccs_parse_ipaddr(ccs_read_token(param), e->ip)) {
+		case 1:
+		case 2:
+			e->is_ipv6 = false;
+			break;
+		case 3:
+		case 4:
+			e->is_ipv6 = true;
+			break;
+		default:
+			goto out;
+		}
+		error = ccs_update_policy(sizeof(*e), param);
 #endif
 	}
 out:
@@ -4323,54 +4036,55 @@
  */
 static int ccs_write_transition_control(struct ccs_acl_param *param)
 {
-	param->list = &param->ns->default_transition_list;
-	return ccs_update_execute_acl(param);
+	param->list = &ccs_default_transition_list;
+	param->e.acl_info.type = CCS_MAC_FILE_EXECUTE;
+	return ccs_update_acl(0, param);
 }
 
 /**
- * ccs_update_domain_in_acl - Update "struct ccs_domain_info" in "struct ccs_acl_info".
+ * ccs_update_acl_in_acl - Update "struct ccs_acl_info" in "struct ccs_acl_info".
  *
  * @acl:   Pointer to "struct ccs_acl_info".
  * @param: Pointer to "struct ccs_acl_param".
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_update_domain_in_acl(struct ccs_acl_info *acl,
-				    struct ccs_acl_param *param)
+static int ccs_update_acl_in_acl(struct ccs_acl_info *acl,
+				 struct ccs_acl_param *param)
 {
-	struct ccs_domain_info *ptr;
-	struct ccs_domain_info domain = { };
+	struct ccs_acl_info *ptr;
+	struct ccs_acl_info acl2 = { };
 	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	domain.domainname = ccs_get_domainname(param);
-	if (!domain.domainname)
-		return error;
 	if (param->data[0]) {
-		domain.cond = ccs_get_condition(param);
-		if (!domain.cond)
+		char *line = kstrdup(param->data, CCS_GFP_FLAGS); 
+		acl2.cond = ccs_get_condition(param);
+		if (!acl2.cond)
+			printk(KERN_WARNING "%u: '%s' failed\n"
+			       , __LINE__, line);
+		kfree(line);
+		if (!acl2.cond)
 			goto out;
 	}
 	mutex_lock(&ccs_policy_lock);
-	list_for_each_entry_srcu(ptr, &acl->domain_list, list, &ccs_ss) {
-		if (ptr->cond != domain.cond ||
-		    ptr->domainname != domain.domainname)
+	list_for_each_entry_srcu(ptr, &acl->acl_info_list, list, &ccs_ss) {
+		if (ptr->cond != acl2.cond)
 			continue;
 		ptr->is_deleted = param->is_delete;
 		error = 0;
 		break;
 	}
 	if (!param->is_delete && error) {
-		struct ccs_domain_info *entry =
-			ccs_commit_ok(&domain, sizeof(domain));
+		struct ccs_acl_info *entry =
+			ccs_commit_ok(&acl2, sizeof(acl2));
 		if (entry) {
 			INIT_LIST_HEAD(&entry->acl_info_list);
-			list_add_tail_rcu(&entry->list, &acl->domain_list);
+			list_add_tail_rcu(&entry->list, &acl->acl_info_list);
 			error = 0;
 		}
 	}
 	mutex_unlock(&ccs_policy_lock);
 out:
-	ccs_put_name(domain.domainname);
-	ccs_put_condition(domain.cond);
+	ccs_put_condition(acl2.cond);
 	return error;
 }
 
@@ -4383,35 +4097,14 @@
  */
 static int ccs_write_acl_policy(struct ccs_io_buffer *head)
 {
-	static const struct {
-		const char *keyword;
-		int (*write) (struct ccs_acl_param *);
-	} ccs_callback[] = {
-		{ "file ", ccs_write_file },
-#ifdef CONFIG_CCSECURITY_NETWORK
-		{ "network inet ", ccs_write_inet_network },
-		{ "network unix ", ccs_write_unix_network },
-#endif
-#ifdef CONFIG_CCSECURITY_MISC
-		{ "misc ", ccs_write_misc },
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-		{ "capability ", ccs_write_capability },
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-		{ "ipc ptrace ", ccs_write_ipc },
-#endif
-	};
 	struct ccs_acl_param param = {
 		.data = head->write_buf,
 		.is_delete = head->w.is_delete,
-		.e.acl_info.perm = 1,
 	};
-	u8 i;
-	if (ccs_str_starts(&param.data, "by ")) {
+	if (ccs_str_starts(&param.data, "allow ")) {
 		if (!head->w.acl)
 			return -EINVAL;
-		return ccs_update_domain_in_acl(head->w.acl, &param);
+		return ccs_update_acl_in_acl(head->w.acl, &param);
 	}
 	if (ccs_str_starts(&param.data, "mode ")) {
 		u8 mode;
@@ -4425,13 +4118,8 @@
 		return -EINVAL;
 	}
 	head->w.acl = NULL;
-	if (!ccs_str_starts(&param.data, "allow "))
-		return -EINVAL;
-	for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
-		int error;
-		if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
-			continue;
-		error = ccs_callback[i].write(&param);
+	if (ccs_str_starts(&param.data, "acl ")) {
+		int error = ccs_parse_entry(&param);
 		if (!error && !head->w.is_delete)
 			head->w.acl = param.matched_entry;
 		ccs_del_acl(&param.e.acl_info.list);
@@ -4451,14 +4139,12 @@
 {
 	const bool is_delete = head->w.is_delete;
 	struct ccs_acl_param param = {
-		.ns = head->w.ns,
 		.is_delete = is_delete,
 		.data = head->write_buf,
 	};
 	u8 i;
 	/* Forced zero clear for using memcmp() at ccs_update_policy(). */
 	memset(&param.e, 0, sizeof(param.e));
-	param.e.acl_info.perm = 1;
 	if (ccs_str_starts(&param.data, "default_transition "))
 		return ccs_write_transition_control(&param);
 	for (i = 0; i < CCS_MAX_GROUP; i++)
@@ -4479,9 +4165,7 @@
  */
 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx)
 {
-	struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
-						       namespace_list);
-	struct list_head *list = &ns->group_list[idx];
+	struct list_head *list = &ccs_group_list[idx];
 	if (idx == CCS_ACL_GROUP) {
 		list_for_each_cookie(head->r.group, list) {
 			struct ccs_group *group =
@@ -4491,11 +4175,9 @@
 			printk(KERN_INFO "%s ptr=%p\n", __func__, group);
 			*/
 			head->r.acl_group_name = group->group_name;
-			head->r.domain = &group->member_list;
-			if (!ccs_read_acl(head, head->r.domain))
+			if (!ccs_read_acl(head, &group->member_list))
 				return false;
 			head->r.acl_group_name = NULL;
-			head->r.domain = NULL;
 		}
 		head->r.group = NULL;
 		return true;
@@ -4510,7 +4192,6 @@
 				continue;
 			if (!ccs_flush(head))
 				return false;
-			ccs_print_namespace(head);
 			ccs_set_string(head, ccs_group_name[idx]);
 			ccs_set_string(head, group->group_name->name);
 			if (idx == CCS_PATH_GROUP) {
@@ -4519,9 +4200,19 @@
 					       (ptr, struct ccs_path_group,
 						head)->member_name->name);
 			} else if (idx == CCS_NUMBER_GROUP) {
-				ccs_print_number_union(head, &container_of
-					       (ptr, struct ccs_number_group,
-						head)->number);
+				ccs_set_space(head);
+				struct ccs_number_group *e =
+					container_of(ptr,
+						     struct ccs_number_group,
+						     head);
+				ccs_print_number(head, e->radix & 3,
+						 e->value[0]);
+				if (e->radix >> 2) {
+					ccs_set_string(head, "-");
+					ccs_print_number(head,
+							 (e->radix >> 2) & 3,
+							 e->value[1]);
+				}
 #ifdef CONFIG_CCSECURITY_NETWORK
 			} else if (idx == CCS_ADDRESS_GROUP) {
 				char buffer[128];
@@ -4529,7 +4220,7 @@
 					container_of(ptr, typeof(*member),
 						     head);
 				ccs_print_ip(buffer, sizeof(buffer),
-					     &member->address);
+					     member->is_ipv6, member->ip);
 				ccs_io_printf(head, " %s", buffer);
 #endif
 			}
@@ -4552,8 +4243,6 @@
  */
 static void ccs_read_exception(struct ccs_io_buffer *head)
 {
-	struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
-						       namespace_list);
 	if (head->r.eof)
 		return;
 	while (head->r.step < CCS_MAX_GROUP)
@@ -4562,7 +4251,7 @@
 		else
 			head->r.step++;
 	head->r.print_default_transition = true;
-	head->r.eof = ccs_read_acl(head, &ns->default_transition_list);
+	head->r.eof = ccs_read_acl(head, &ccs_default_transition_list);
 	head->r.print_default_transition = false;
 }
 
@@ -4592,7 +4281,6 @@
 static void ccs_add_entry(char *header)
 {
 	char *buffer;
-	char *realpath = NULL;
 	char *argv0 = NULL;
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	char *handler;
@@ -4613,11 +4301,6 @@
 			argv0 += 10;
 			len += ccs_truncate(argv0) + 14;
 		}
-		realpath = strstr(header, " exec={ realpath=\"");
-		if (realpath) {
-			realpath += 8;
-			len += ccs_truncate(realpath) + 6;
-		}
 	}
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	handler = strstr(header, "type=execute_handler");
@@ -4632,15 +4315,12 @@
 	if (handler)
 		ccs_addprintf(buffer, len, " task.%s", handler);
 #endif
-	if (realpath)
-		ccs_addprintf(buffer, len, " exec.%s", realpath);
 	if (argv0)
-		ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
+		ccs_addprintf(buffer, len, " argv[0]=%s", argv0);
 	ccs_normalize_line(buffer);
 	{
 		struct ccs_domain_info *domain = ccs_current_domain();
-		if (!ccs_write_acl(domain->ns, &domain->acl_info_list,
-				   buffer, false))
+		if (!ccs_write_acl(&domain->acl_info_list, buffer, false))
 			ccs_update_stat(CCS_STAT_POLICY_UPDATES);
 	}
 	kfree(buffer);
@@ -4665,37 +4345,21 @@
 	if (!domain)
 		return true;
 	list_for_each_entry_srcu(ptr, &domain->acl_info_list, list, &ccs_ss) {
-		u16 perm;
-		u8 i;
 		if (ptr->is_deleted)
 			continue;
 		switch (ptr->type) {
-		case CCS_TYPE_PATH_ACL:
-		case CCS_TYPE_PATH2_ACL:
-		case CCS_TYPE_PATH_NUMBER_ACL:
-		case CCS_TYPE_MKDEV_ACL:
-#ifdef CONFIG_CCSECURITY_NETWORK
-		case CCS_TYPE_INET_ACL:
-		case CCS_TYPE_UNIX_ACL:
-#endif
-			perm = ptr->perm;
-			break;
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-		case CCS_TYPE_AUTO_EXECUTE_HANDLER:
-		case CCS_TYPE_DENIED_EXECUTE_HANDLER:
+		case CCS_MAC_AUTO_EXECUTE_HANDLER:
+		case CCS_MAC_DENIED_EXECUTE_HANDLER:
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-		case CCS_TYPE_AUTO_TASK_ACL:
-		case CCS_TYPE_MANUAL_TASK_ACL:
+		case CCS_MAC_AUTO_TASK_TRANSITION:
+		case CCS_MAC_MANUAL_TASK_TRANSITION:
 #endif
-			perm = 0;
 			break;
 		default:
-			perm = 1;
+			count++;
 		}
-		for (i = 0; i < 16; i++)
-			if (perm & (1 << i))
-				count++;
 	}
 	if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY])
 		return true;
@@ -4839,101 +4503,232 @@
  */
 int ccs_audit_log(struct ccs_request_info *r)
 {
-	switch (r->param_type) {
-		u8 type;
-		char buf[48];
+	const char *keyword = ccs_mac_keywords[r->type];
+	if (WARN_ON(!keyword))
+		return 0;
+	switch (r->type) {
 #ifdef CONFIG_CCSECURITY_NETWORK
-		const u32 *address;
+		char buf[48];
 #endif
-	case CCS_TYPE_EXECUTE_ACL:
-		return ccs_supervisor(r, "file execute %s\n",
-				      r->param.path.filename->name);
-	case CCS_TYPE_PATH_ACL:
-		return ccs_supervisor(r, "file %s %s\n", ccs_mac_keywords
-				      [ccs_p2mac[r->param.path.operation]],
-				      r->param.path.filename->name);
-	case CCS_TYPE_PATH2_ACL:
-		return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
-				      [ccs_pp2mac[r->param.path2.operation]],
-				      r->param.path2.filename1->name,
-				      r->param.path2.filename2->name);
-	case CCS_TYPE_PATH_NUMBER_ACL:
-		type = r->param.path_number.operation;
-		switch (type) {
-		case CCS_TYPE_CREATE:
-		case CCS_TYPE_MKDIR:
-		case CCS_TYPE_MKFIFO:
-		case CCS_TYPE_MKSOCK:
-		case CCS_TYPE_CHMOD:
-			snprintf(buf, sizeof(buf), "0%lo",
-				 r->param.path_number.number);
-			break;
-		case CCS_TYPE_IOCTL:
-			snprintf(buf, sizeof(buf), "0x%lX",
-				 r->param.path_number.number);
-			break;
-		default:
-			snprintf(buf, sizeof(buf), "%lu",
-				 r->param.path_number.number);
-			break;
-		}
-		return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
-				      [ccs_pn2mac[type]],
-				      r->param.path_number.filename->name,
-				      buf);
-	case CCS_TYPE_MKDEV_ACL:
-		return ccs_supervisor(r, "file %s %s 0%o %u %u\n",
-				      ccs_mac_keywords
-				      [ccs_pnnn2mac[r->param.mkdev.operation]],
-				      r->param.mkdev.filename->name,
-				      r->param.mkdev.mode,
-				      r->param.mkdev.major,
-				      r->param.mkdev.minor);
-	case CCS_TYPE_MOUNT_ACL:
-		return ccs_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);
+	case CCS_MAC_FILE_EXECUTE:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		if (WARN_ON(!r->param.s[1]))
+			return 0;
+		if (WARN_ON(!r->param.s[1]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s exec=\"%s\" path=\"%s\"\n",
+				      keyword, r->param.s[1]->name,
+				      r->param.s[0]->name);
+	case CCS_MAC_FILE_READ:
+	case CCS_MAC_FILE_WRITE:
+	case CCS_MAC_FILE_APPEND:
+	case CCS_MAC_FILE_UNLINK:
+	case CCS_MAC_FILE_GETATTR:
+	case CCS_MAC_FILE_RMDIR:
+	case CCS_MAC_FILE_TRUNCATE:
+	case CCS_MAC_FILE_CHROOT:
+	case CCS_MAC_FILE_UMOUNT:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\"\n", keyword,
+				      r->param.s[0]->name);
+	case CCS_MAC_FILE_CREATE:
+	case CCS_MAC_FILE_MKDIR:
+	case CCS_MAC_FILE_MKFIFO:
+	case CCS_MAC_FILE_MKSOCK:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" perm=0%lo\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0]);
+	case CCS_MAC_FILE_SYMLINK:
+		return ccs_supervisor(r, "file %s path=\"%s\" target=\"%s\""
+				      "\n", keyword, r->param.s[0]->name,
+				      r->param.s[1]->name);
+	case CCS_MAC_FILE_MKBLOCK:
+	case CCS_MAC_FILE_MKCHAR:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" perm=0%lo "
+				      "dev_major=%lu dev_minor=%lu\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0], r->param.i[1],
+				      r->param.i[2]);
+	case CCS_MAC_FILE_LINK:
+	case CCS_MAC_FILE_RENAME:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		if (WARN_ON(!r->param.s[1]))
+			return 0;
+		if (WARN_ON(!r->param.s[1]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s old_path=\"%s\" "
+				      "new_path=\"%s\"\n", keyword,
+				      r->param.s[0]->name,
+				      r->param.s[1]->name);
+	case CCS_MAC_FILE_CHMOD:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" perm=0%lo\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0]);
+	case CCS_MAC_FILE_CHOWN:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" uid=%lu\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0]);
+	case CCS_MAC_FILE_CHGRP:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" gid=%lu\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0]);
+	case CCS_MAC_FILE_IOCTL:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s path=\"%s\" cmd=0x%lX\n",
+				      keyword, r->param.s[0]->name,
+				      r->param.i[0]);
+	case CCS_MAC_FILE_MOUNT:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		if (WARN_ON(!r->param.s[1]))
+			return 0;
+		if (WARN_ON(!r->param.s[1]->name))
+			return 0;
+		if (WARN_ON(!r->param.s[2]))
+			return 0;
+		if (WARN_ON(!r->param.s[2]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s source=\"%s\" target=\"%s\" "
+				      "fstype=\"%s\" flags=0x%lX\n", keyword,
+				      r->param.s[0]->name, r->param.s[1]->name,
+				      r->param.s[2]->name, r->param.i[0]);
+	case CCS_MAC_FILE_PIVOT_ROOT:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		if (WARN_ON(!r->param.s[1]))
+			return 0;
+		if (WARN_ON(!r->param.s[1]->name))
+			return 0;
+		return ccs_supervisor(r, "file %s new_root=\"%s\" "
+				      "put_old=\"%s\"\n", keyword,
+				      r->param.s[0]->name,
+				      r->param.s[1]->name);
 #ifdef CONFIG_CCSECURITY_MISC
-	case CCS_TYPE_ENV_ACL:
-		return ccs_supervisor(r, "misc env %s\n",
-				      r->param.environ.name->name);
+	case CCS_MAC_ENVIRON:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "misc %s name=\"%s\"\n", keyword,
+				      r->param.s[0]->name);
 #endif
+
 #ifdef CONFIG_CCSECURITY_CAPABILITY
-	case CCS_TYPE_CAPABILITY_ACL:
-		return ccs_supervisor(r, "capability %s\n", ccs_mac_keywords
-				      [ccs_c2mac[r->param.capability.
-						 operation]]);
+	case CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET:
+	case CCS_MAC_CAPABILITY_USE_PACKET_SOCKET:
+	case CCS_MAC_CAPABILITY_SYS_REBOOT:
+	case CCS_MAC_CAPABILITY_SYS_VHANGUP:
+	case CCS_MAC_CAPABILITY_SYS_SETTIME:
+	case CCS_MAC_CAPABILITY_SYS_NICE:
+	case CCS_MAC_CAPABILITY_SYS_SETHOSTNAME:
+	case CCS_MAC_CAPABILITY_USE_KERNEL_MODULE:
+	case CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD:
+		return 0; /////
+		return ccs_supervisor(r, "capability %s\n", keyword);
 #endif
 #ifdef CONFIG_CCSECURITY_NETWORK
-	case CCS_TYPE_INET_ACL:
-		address = r->param.inet_network.address;
-		if (r->param.inet_network.is_ipv6)
+	case CCS_MAC_NETWORK_INET_STREAM_BIND:
+	case CCS_MAC_NETWORK_INET_STREAM_LISTEN:
+	case CCS_MAC_NETWORK_INET_STREAM_CONNECT:
+	case CCS_MAC_NETWORK_INET_STREAM_ACCEPT:
+	case CCS_MAC_NETWORK_INET_DGRAM_BIND:
+	case CCS_MAC_NETWORK_INET_DGRAM_SEND:
+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
+	case CCS_MAC_NETWORK_INET_DGRAM_RECV:
+#endif
+		if (WARN_ON(!r->param.ip))
+			return 0;
+		if (r->param.is_ipv6)
 			ccs_print_ipv6(buf, sizeof(buf),
-				       (const struct in6_addr *) address);
+				       (const struct in6_addr *) r->param.ip);
 		else
-			ccs_print_ipv4(buf, sizeof(buf), address);
-		return ccs_supervisor(r, "network inet %s %s %s %u\n",
-				      ccs_proto_keyword[r->param.inet_network.
-							protocol],
-				      ccs_socket_keyword[r->param.inet_network.
-							 operation],
-				      buf, r->param.inet_network.port);
-	case CCS_TYPE_UNIX_ACL:
-		return ccs_supervisor(r, "network unix %s %s %s\n",
-				      ccs_proto_keyword[r->param.
-							unix_network.protocol],
-				      ccs_socket_keyword[r->param.unix_network.
-							 operation],
-				      r->param.unix_network.address->name);
+			ccs_print_ipv4(buf, sizeof(buf), r->param.ip);
+		return ccs_supervisor(r, "network %s ip=%s port=%lu\n",
+				      keyword, buf, r->param.i[0]);
+	case CCS_MAC_NETWORK_INET_RAW_BIND:
+	case CCS_MAC_NETWORK_INET_RAW_SEND:
+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
+	case CCS_MAC_NETWORK_INET_RAW_RECV:
 #endif
+		if (WARN_ON(!r->param.ip))
+			return 0;
+		if (r->param.is_ipv6)
+			ccs_print_ipv6(buf, sizeof(buf),
+				       (const struct in6_addr *) r->param.ip);
+		else
+			ccs_print_ipv4(buf, sizeof(buf), r->param.ip);
+		return ccs_supervisor(r, "network %s ip=%s proto=%lu\n",
+				      keyword, buf, r->param.i[0]);
+	case CCS_MAC_NETWORK_UNIX_STREAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_STREAM_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_STREAM_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_BIND:
+	case CCS_MAC_NETWORK_UNIX_DGRAM_SEND:
+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
+	case CCS_MAC_NETWORK_UNIX_DGRAM_RECV:
+#endif
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT:
+	case CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT:
+		if (WARN_ON(!r->param.s[0]))
+			return 0;
+		if (WARN_ON(!r->param.s[0]->name))
+			return 0;
+		return ccs_supervisor(r, "network %s addr=\"%s\"\n", keyword,
+				      r->param.s[0]->name);
+#endif
 #ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_PTRACE_ACL:
-		return ccs_supervisor(r, "ipc ptrace %lu %s\n",
-				      r->param.ptrace.request,
-				      r->param.ptrace.domainname);
+	case CCS_MAC_PTRACE:
+		return 0; /////
+		return ccs_supervisor(r, "ipc %s cmd=%lu domain=\"%s\"\n",
+				      keyword, r->param.i[0],
+				      r->param.s[0]->name);
 #endif
+	case CCS_MAX_MAC_INDEX:
+	case CCS_MAC_AUTO_EXECUTE_HANDLER:
+	case CCS_MAC_DENIED_EXECUTE_HANDLER:
+	case CCS_MAC_AUTO_TASK_TRANSITION:
+	case CCS_MAC_MANUAL_TASK_TRANSITION:
+	case CCS_MAC_USE_GROUP:
+		break;
 	}
 	return 0;
 }
@@ -5234,10 +5029,7 @@
 			if (cp >= buffer + ccs_buffer_len - 32) {
 				/* Reserve some room for "..." string. */
 				truncated = true;
-			} else if (c == '\\') {
-				*cp++ = '\\';
-				*cp++ = '\\';
-			} else if (c > ' ' && c < 127) {
+			} else if (c > ' ' && c < 127 && c != '\\') {
 				*cp++ = c;
 			} else if (!c) {
 				*cp++ = '"';
@@ -5297,19 +5089,19 @@
 	switch (mode & S_IFMT) {
 	case S_IFREG:
 	case 0:
-		return ccs_condition_keyword[CCS_TYPE_IS_FILE];
+		return "file";
 	case S_IFDIR:
-		return ccs_condition_keyword[CCS_TYPE_IS_DIRECTORY];
+		return "directory";
 	case S_IFLNK:
-		return ccs_condition_keyword[CCS_TYPE_IS_SYMLINK];
+		return "symlink";
 	case S_IFIFO:
-		return ccs_condition_keyword[CCS_TYPE_IS_FIFO];
+		return "fifo";
 	case S_IFSOCK:
-		return ccs_condition_keyword[CCS_TYPE_IS_SOCKET];
+		return "socket";
 	case S_IFBLK:
-		return ccs_condition_keyword[CCS_TYPE_IS_BLOCK_DEV];
+		return "block";
 	case S_IFCHR:
-		return ccs_condition_keyword[CCS_TYPE_IS_CHAR_DEV];
+		return "char";
 	}
 	return "unknown"; /* This should not happen. */
 }
@@ -5370,6 +5162,7 @@
 		obj->validate_done = true;
 	}
 	for (i = 0; i < CCS_MAX_PATH_STAT; i++) {
+		const char *objname; 
 		struct ccs_mini_stat *stat;
 		unsigned int dev;
 		umode_t mode;
@@ -5378,17 +5171,18 @@
 		stat = &obj->stat[i];
 		dev = stat->dev;
 		mode = stat->mode;
+		objname = ccs_get_sarg(r->type, (i >> 1));
 		if (i & 1) {
 			pos += snprintf(buffer + pos, ccs_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);
+					" %s.parent={ uid=%u gid=%u ino=%lu "
+					"perm=0%o }", objname, stat->uid,
+					stat->gid, (unsigned long) stat->ino,
+					stat->mode & S_IALLUGO);
 			continue;
 		}
 		pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos,
-				" path%u={ uid=%u gid=%u ino=%lu major=%u"
-				" minor=%u perm=0%o type=%s", (i >> 1) + 1,
+				" %s={ uid=%u gid=%u ino=%lu major=%u"
+				" minor=%u perm=0%o type=%s", objname,
 				stat->uid, stat->gid, (unsigned long)
 				stat->ino, MAJOR(dev), MINOR(dev),
 				mode & S_IALLUGO, ccs_filetype(mode));
@@ -5425,7 +5219,7 @@
 {
 	char *buf = NULL;
 	char *bprm_info = NULL;
-	char *realpath = NULL;
+	char *exe = NULL;
 	const char *header = NULL;
 	int pos;
 	const char *domainname = ccs_current_domain()->domainname->name;
@@ -5438,15 +5232,15 @@
 		struct file *file = r->ee->bprm->file;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
 		struct path path = { file->f_vfsmnt, file->f_dentry };
-		realpath = ccs_realpath(&path);
+		exe = ccs_realpath(&path);
 #else
-		realpath = ccs_realpath(&file->f_path);
+		exe = ccs_realpath(&file->f_path);
 #endif
 		bprm_info = ccs_print_bprm(r->ee->bprm, &r->ee->dump);
-		if (!realpath || !bprm_info)
+		if (!exe || !bprm_info)
 			goto out;
-		/* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
-		len += strlen(realpath) + 80 + strlen(bprm_info);
+		/* +80 is for " argc=%d envc=%d %s " */
+		len += strlen(exe) + 80 + strlen(bprm_info);
 	}
 	len = ccs_round2(len);
 	buf = kzalloc(len, CCS_GFP_FLAGS);
@@ -5454,16 +5248,16 @@
 		goto out;
 	len--;
 	pos = snprintf(buf, len, "%s", header);
-	if (realpath) {
+	if (exe) {
 		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);
+				" exec={ path=\"%s\" argc=%d envc=%d %s }",
+				exe, bprm->argc, bprm->envc, bprm_info);
 	}
 	pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
 	vsnprintf(buf + pos, len - pos, fmt, args);
 out:
-	kfree(realpath);
+	kfree(exe);
 	kfree(bprm_info);
 	kfree(header);
 	return buf;
@@ -5488,13 +5282,6 @@
 	p = ccs_profile(profile);
 	if (ccs_log_count >= p->pref[CCS_PREF_MAX_AUDIT_LOG])
 		return false;
-	if (is_granted) {
-		const struct ccs_acl_info *matched_acl = r->matched_acl;
-		if (matched_acl && matched_acl->cond &&
-		    matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO)
-			return matched_acl->cond->grant_log ==
-				CCS_GRANTLOG_YES;
-	}
 	mode = p->config[index];
 	if (mode == CCS_CONFIG_USE_DEFAULT)
 		mode = p->config
@@ -5626,129 +5413,8 @@
 }
 
 /**
- * ccs_set_namespace_cursor - Set namespace to read.
+ * ccs_assign_domain - Create a domain.
  *
- * @head: Pointer to "struct ccs_io_buffer".
- *
- * Returns nothing.
- */
-static void ccs_set_namespace_cursor(struct ccs_io_buffer *head)
-{
-	struct list_head *ns;
-	if (head->type != CCS_EXCEPTION_POLICY && head->type != CCS_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 != &ccs_namespace_list)) {
-		/* Clearing is OK because ccs_flush() returned true. */
-		memset(&head->r, 0, sizeof(head->r));
-		head->r.ns = ns ? ns->next : ccs_namespace_list.next;
-	}
-}
-
-/**
- * ccs_has_more_namespace - Check for unread namespaces.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- *
- * Returns true if we have more entries to print, false otherwise.
- */
-static bool ccs_has_more_namespace(struct ccs_io_buffer *head)
-{
-	return (head->type == CCS_EXCEPTION_POLICY ||
-		head->type == CCS_PROFILE) && head->r.eof &&
-		head->r.ns->next != &ccs_namespace_list;
-}
-
-/**
- * ccs_find_namespace - Find specified namespace.
- *
- * @name: Name of namespace to find.
- * @len:  Length of @name.
- *
- * Returns pointer to "struct ccs_policy_namespace" if found, NULL otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
-						       const unsigned int len)
-{
-	struct ccs_policy_namespace *ns;
-	list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list,
-				 &ccs_ss) {
-		if (strncmp(name, ns->name, len) ||
-		    (name[len] && name[len] != ' '))
-			continue;
-		return ns;
-	}
-	return NULL;
-}
-
-/**
- * ccs_assign_namespace - Create a new namespace.
- *
- * @domainname: Name of namespace to create.
- *
- * Returns pointer to "struct ccs_policy_namespace" on success, NULL otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static struct ccs_policy_namespace *ccs_assign_namespace
-(const char *domainname)
-{
-	struct ccs_policy_namespace *ptr;
-	struct ccs_policy_namespace *entry;
-	const char *cp = domainname;
-	unsigned int len = 0;
-	while (*cp && *cp++ != ' ')
-		len++;
-	ptr = ccs_find_namespace(domainname, len);
-	if (ptr)
-		return ptr;
-	if (len >= CCS_EXEC_TMPSIZE - 10 || !ccs_domain_def(domainname))
-		return NULL;
-	entry = kzalloc(sizeof(*entry) + len + 1, CCS_GFP_FLAGS);
-	if (!entry)
-		return NULL;
-	if (mutex_lock_interruptible(&ccs_policy_lock))
-		goto out;
-	ptr = ccs_find_namespace(domainname, len);
-	if (!ptr && ccs_memory_ok(entry, sizeof(*entry) + len + 1)) {
-		char *name = (char *) (entry + 1);
-		ptr = entry;
-		memmove(name, domainname, len);
-		name[len] = '\0';
-		entry->name = name;
-		ccs_init_policy_namespace(entry);
-		entry = NULL;
-	}
-	mutex_unlock(&ccs_policy_lock);
-out:
-	kfree(entry);
-	return ptr;
-}
-
-/**
- * ccs_namespace_jump - Check for namespace jump.
- *
- * @domainname: Name of domain.
- *
- * Returns true if namespace differs, false otherwise.
- */
-static bool ccs_namespace_jump(const char *domainname)
-{
-	const char *namespace = ccs_current_namespace()->name;
-	const int len = strlen(namespace);
-	return strncmp(domainname, namespace, len) ||
-		(domainname[len] && domainname[len] != ' ');
-}
-
-/**
- * ccs_assign_domain - Create a domain or a namespace.
- *
  * @domainname: The name of domain.
  * @transit:    True if transit to domain found or created.
  *
@@ -5764,18 +5430,8 @@
 	struct ccs_domain_info *entry = ccs_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 (ccs_policy_loaded &&
-			    !entry->ns->profile_ptr[entry->profile])
-				return NULL;
+		if (transit)
 			security->ccs_domain_info = entry;
-		}
 		return entry;
 	}
 	/* Requested domain does not exist. */
@@ -5783,16 +5439,6 @@
 	if (strlen(domainname) >= CCS_EXEC_TMPSIZE - 10 ||
 	    !ccs_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 && ccs_namespace_jump(domainname))
-		return NULL;
-	e.ns = ccs_assign_namespace(domainname);
-	if (!e.ns)
-		return NULL;
 	e.domainname = ccs_get_name(domainname);
 	if (!e.domainname)
 		return NULL;
@@ -5826,8 +5472,7 @@
 			printk(KERN_INFO "ptr->is_deleted=%u ptr->type=%u\n",
 			       ptr->is_deleted, ptr->type);
 			*/
-			if (ptr->is_deleted ||
-			    ptr->type != CCS_TYPE_USE_GROUP_ACL)
+			if (ptr->is_deleted || ptr->type != CCS_MAC_USE_GROUP)
 				continue;
 			tmp = *container_of(ptr, typeof(tmp), head);
 			atomic_inc(&tmp.group->head.users);
@@ -5883,22 +5528,6 @@
 	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 == CCS_EXCEPTION_POLICY || head->type == CCS_PROFILE) {
-		if (*line == '<') {
-			char *cp = strchr(line, ' ');
-			if (cp) {
-				*cp++ = '\0';
-				head->w.ns = ccs_assign_namespace(line);
-				memmove(line, cp, strlen(cp) + 1);
-			} else
-				head->w.ns = NULL;
-		} else
-			head->w.ns = &ccs_kernel_namespace;
-		/* Don't allow updating if namespace is invalid. */
-		if (!head->w.ns)
-			return -ENOENT;
-	}
 	/* Do the update. */
 	switch (head->type) {
 	case CCS_DOMAIN_POLICY:
@@ -6021,7 +5650,7 @@
 }
 
 /**
- * ccs_read_domain_in_acl - Read domainname and condition.
+ * ccs_read_acl_in_acl - Read inverse mode conditions.
  *
  * @head: Pointer to "struct ccs_io_buffer".
  * @list: Pointer to "struct list_head".
@@ -6030,32 +5659,31 @@
  *
  * Caller holds ccs_read_lock().
  */
-static bool ccs_read_domain_in_acl(struct ccs_io_buffer *head,
-				   struct list_head *list)
+static bool ccs_read_acl_in_acl(struct ccs_io_buffer *head,
+				const enum ccs_mac_index type,
+				const struct list_head *list)
 {
 	list_for_each_cookie(head->r.domain, list) {
-		struct ccs_domain_info *domain =
-			list_entry(head->r.domain, typeof(*domain), list);
+		struct ccs_acl_info *acl =
+			list_entry(head->r.domain, typeof(*acl), list);
 		switch (head->r.step) {
 		case 3:
-			if (domain->is_deleted)
+			if (acl->is_deleted)
 				continue;
 			if (!ccs_flush(head))
 				return false;
-			ccs_set_string(head, "    by ");
-			ccs_set_string(head, domain->domainname->name);
+			ccs_set_string(head, "    allow");
 			head->r.cond_step = 0;
 			head->r.step++;
 			/* fall through */
 		case 4:
 			if (!ccs_flush(head))
 				return false;
-			if (domain->cond) {
-				if (!ccs_print_condition(head, domain->cond))
-					return false;
-			} else {
-				ccs_set_lf(head);
-			}
+			if (acl->cond &&
+			    !ccs_print_condition(head, type,
+						 acl->cond))
+				return false;
+			ccs_set_lf(head);
 			head->r.step--;
 		}
 	}
@@ -6098,7 +5726,8 @@
 			/* fall through */
 		case 3:
 		case 4:
-			if (!ccs_read_domain_in_acl(head, &ptr->domain_list))
+			if (!ccs_read_acl_in_acl(head, ptr->type,
+						 &ptr->acl_info_list))
 				return;
 			head->r.domain = NULL;
 			head->r.step = 5;
@@ -6232,46 +5861,45 @@
 	head->read_user_buf = buf;
 	head->read_user_buf_avail = count;
 	idx = ccs_read_lock();
-	if (ccs_flush(head))
+	if (ccs_flush(head)) {
 		/* Call the policy handler. */
-		do {
-			ccs_set_namespace_cursor(head);
-			switch (head->type) {
-			case CCS_DOMAIN_POLICY:
-				ccs_read_domain(head);
-				break;
-			case CCS_EXCEPTION_POLICY:
-				ccs_read_exception(head);
-				break;
-			case CCS_AUDIT:
-				ccs_read_log(head);
-				break;
+		switch (head->type) {
+		case CCS_DOMAIN_POLICY:
+			ccs_read_domain(head);
+			break;
+		case CCS_EXCEPTION_POLICY:
+			ccs_read_exception(head);
+			break;
+		case CCS_AUDIT:
+			ccs_read_log(head);
+			break;
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-			case CCS_EXECUTE_HANDLER:
+		case CCS_EXECUTE_HANDLER:
 #endif
-			case CCS_PROCESS_STATUS:
-				ccs_read_pid(head);
-				break;
-			case CCS_VERSION:
-				ccs_read_version(head);
-				break;
-			case CCS_STAT:
-				ccs_read_stat(head);
-				break;
-			case CCS_PROFILE:
-				ccs_read_profile(head);
-				break;
-			case CCS_QUERY:
-				ccs_read_query(head);
-				break;
-			case CCS_MANAGER:
-				ccs_read_manager(head);
-				break;
-			case CCS_ACL_POLICY:
-				ccs_read_inverse_policy(head);
-				break;
-			}
-		} while (ccs_flush(head) && ccs_has_more_namespace(head));
+		case CCS_PROCESS_STATUS:
+			ccs_read_pid(head);
+			break;
+		case CCS_VERSION:
+			ccs_read_version(head);
+			break;
+		case CCS_STAT:
+			ccs_read_stat(head);
+			break;
+		case CCS_PROFILE:
+			ccs_read_profile(head);
+			break;
+		case CCS_QUERY:
+			ccs_read_query(head);
+			break;
+		case CCS_MANAGER:
+			ccs_read_manager(head);
+			break;
+		case CCS_ACL_POLICY:
+			ccs_read_inverse_policy(head);
+			break;
+		}
+		ccs_flush(head);
+	}
 	ccs_read_unlock(idx);
 	len = head->read_user_buf - buf;
 	mutex_unlock(&head->io_sem);
@@ -6315,9 +5943,8 @@
 		name.name = data;
 		ccs_fill_path_info(&name);
 		/* Check "task manual_domain_transition" permission. */
-		r.type = CCS_MAC_FILE_EXECUTE;
-		r.param_type = CCS_TYPE_MANUAL_TASK_ACL;
-		r.param.task.domainname = &name;
+		r.type = CCS_MAC_MANUAL_TASK_TRANSITION;
+		r.param.s[0] = &name;
 		ccs_check_acl(&r);
 		if (!r.granted)
 			error = -EPERM;
@@ -6383,7 +6010,6 @@
 		head->w.avail = 0;
 		ccs_normalize_line(cp0);
 		if (!strcmp(cp0, "reset")) {
-			head->w.ns = &ccs_kernel_namespace;
 			head->w.domain = NULL;
 			memset(&head->r, 0, sizeof(head->r));
 			continue;
@@ -6510,6 +6136,7 @@
  */
 static int __init ccs_init_module(void)
 {
+	u8 idx;
 	if (ccsecurity_ops.disabled)
 		return -EINVAL;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
@@ -6519,20 +6146,12 @@
 	if (init_srcu_struct(&ccs_ss))
 		panic("Out of memory.");
 #endif
-	{
-		static struct ccs_path_info any;
-		any.name = "any";
-		ccs_fill_path_info(&any);
-		ccs_group_any.group_name = &any;
-		INIT_LIST_HEAD(&ccs_group_any.head.list);
-		INIT_LIST_HEAD(&ccs_group_any.member_list);
-	}
-	ccs_kernel_namespace.name = "<kernel>";
-	ccs_init_policy_namespace(&ccs_kernel_namespace);
+	for (idx = 0; idx < CCS_MAX_GROUP; idx++)
+		INIT_LIST_HEAD(&ccs_group_list[idx]);
+	INIT_LIST_HEAD(&ccs_default_transition_list);
 	ccs_kernel_transition.name = "child";
 	ccs_fill_path_info(&ccs_kernel_transition);
 	ccs_kernel_domain.default_transition = &ccs_kernel_transition;
-	ccs_kernel_domain.ns = &ccs_kernel_namespace;
 	INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
 	ccs_mm_init();
 	ccs_policy_io_init();
Index: memory.c
===================================================================
--- memory.c	(revision 5811)
+++ memory.c	(working copy)
@@ -162,8 +162,11 @@
 #else
 	head = &ccs_name_list[hash % CCS_MAX_HASH];
 #endif
-	if (mutex_lock_interruptible(&ccs_policy_lock))
+	if (mutex_lock_interruptible(&ccs_policy_lock)) {
+		printk(KERN_INFO "ccs_get_name('%s') interrupted\n", name);
+		WARN_ON(1);
 		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) == CCS_GC_IN_PROGRESS)
Index: permission.c
===================================================================
--- permission.c	(revision 5811)
+++ permission.c	(working copy)
@@ -42,112 +42,12 @@
 	[CCS_MOUNT_MAKE_SHARED]     = "--make-shared",
 };
 
-/* Mapping table from "enum ccs_path_acl_index" to "enum ccs_mac_index". */
-const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
-	[CCS_TYPE_READ]       = CCS_MAC_FILE_READ,
-	[CCS_TYPE_WRITE]      = CCS_MAC_FILE_WRITE,
-	[CCS_TYPE_APPEND]     = CCS_MAC_FILE_APPEND,
-	[CCS_TYPE_UNLINK]     = CCS_MAC_FILE_UNLINK,
-#ifdef CONFIG_CCSECURITY_FILE_GETATTR
-	[CCS_TYPE_GETATTR]    = CCS_MAC_FILE_GETATTR,
-#endif
-	[CCS_TYPE_RMDIR]      = CCS_MAC_FILE_RMDIR,
-	[CCS_TYPE_TRUNCATE]   = CCS_MAC_FILE_TRUNCATE,
-	[CCS_TYPE_CHROOT]     = CCS_MAC_FILE_CHROOT,
-	[CCS_TYPE_UMOUNT]     = CCS_MAC_FILE_UMOUNT,
-};
-
-/* Mapping table from "enum ccs_mkdev_acl_index" to "enum ccs_mac_index". */
-const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION] = {
-	[CCS_TYPE_MKBLOCK] = CCS_MAC_FILE_MKBLOCK,
-	[CCS_TYPE_MKCHAR]  = CCS_MAC_FILE_MKCHAR,
-};
-
-/* Mapping table from "enum ccs_path2_acl_index" to "enum ccs_mac_index". */
-const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION] = {
-	[CCS_TYPE_LINK]       = CCS_MAC_FILE_LINK,
-	[CCS_TYPE_RENAME]     = CCS_MAC_FILE_RENAME,
-	[CCS_TYPE_PIVOT_ROOT] = CCS_MAC_FILE_PIVOT_ROOT,
-	[CCS_TYPE_SYMLINK]    = CCS_MAC_FILE_SYMLINK,
-};
-
-/*
- * Mapping table from "enum ccs_path_number_acl_index" to "enum ccs_mac_index".
- */
-const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION] = {
-	[CCS_TYPE_CREATE] = CCS_MAC_FILE_CREATE,
-	[CCS_TYPE_MKDIR]  = CCS_MAC_FILE_MKDIR,
-	[CCS_TYPE_MKFIFO] = CCS_MAC_FILE_MKFIFO,
-	[CCS_TYPE_MKSOCK] = CCS_MAC_FILE_MKSOCK,
-	[CCS_TYPE_IOCTL]  = CCS_MAC_FILE_IOCTL,
-	[CCS_TYPE_CHMOD]  = CCS_MAC_FILE_CHMOD,
-	[CCS_TYPE_CHOWN]  = CCS_MAC_FILE_CHOWN,
-	[CCS_TYPE_CHGRP]  = CCS_MAC_FILE_CHGRP,
-};
-
-#ifdef CONFIG_CCSECURITY_NETWORK
-
-/*
- * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
- * inet domain socket.
- */
-static const u8 ccs_inet2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
-	[SOCK_STREAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_STREAM_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_INET_STREAM_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_INET_STREAM_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
-	},
-	[SOCK_DGRAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_DGRAM_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_INET_DGRAM_SEND,
-#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_INET_DGRAM_RECV,
-#endif
-	},
-	[SOCK_RAW]    = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_RAW_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_INET_RAW_SEND,
-#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_INET_RAW_RECV,
-#endif
-	},
-};
-
-/*
- * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
- * unix domain socket.
- */
-static const u8 ccs_unix2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
-	[SOCK_STREAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_STREAM_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
-	},
-	[SOCK_DGRAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
-#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
-#endif
-	},
-	[SOCK_SEQPACKET] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
-	},
-};
-
-#endif
-
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 
 /*
  * Mapping table from "enum ccs_capability_acl_index" to "enum ccs_mac_index".
  */
-const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX] = {
+static const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX] = {
 	[CCS_USE_ROUTE_SOCKET]  = CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
 	[CCS_USE_PACKET_SOCKET] = CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
 	[CCS_SYS_REBOOT]        = CCS_MAC_CAPABILITY_SYS_REBOOT,
@@ -165,8 +65,8 @@
 
 /* Structure for holding inet domain socket's address. */
 struct ccs_inet_addr_info {
-	u16 port;           /* In network byte order. */
-	const u32 *address; /* In network byte order. */
+	u16 port;          /* In network byte order. */
+	const u8 *address; /* In network byte order. */
 	bool is_ipv6;
 };
 
@@ -178,7 +78,6 @@
 
 /* Structure for holding socket address. */
 struct ccs_addr_info {
-	u8 protocol;
 	u8 operation;
 	struct ccs_inet_addr_info inet;
 	struct ccs_unix_addr_info unix0;
@@ -191,32 +90,12 @@
 void ccs_get_attributes(struct ccs_obj_info *obj);
 
 static bool ccs_alphabet_char(const char c);
-static bool ccs_argv(const unsigned int index, const char *arg_ptr,
-		     const int argc, const struct ccs_argv *argv, u8 *checked);
 static bool ccs_byte_range(const char *str);
 static bool ccs_check_entry(struct ccs_request_info *r,
 			    struct ccs_acl_info *ptr);
-static bool ccs_check_execute_acl(struct ccs_request_info *r,
-				  const struct ccs_acl_info *ptr);
-static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr);
-static bool ccs_check_mount_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr);
-static bool ccs_check_path2_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr);
-static bool ccs_check_path_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr);
-static bool ccs_check_path_number_acl(struct ccs_request_info *r,
-				      const struct ccs_acl_info *ptr);
-static bool ccs_check_use_group_acl(struct ccs_request_info *r,
-				    struct ccs_acl_info *ptr);
-static bool ccs_compare_number_union(const unsigned long value,
-				     const struct ccs_number_union *ptr);
 static bool ccs_condition(struct ccs_request_info *r,
 			  const struct ccs_condition *cond);
 static bool ccs_decimal(const char c);
-static bool ccs_envp(const char *env_name, const char *env_value,
-		     const int envc, const struct ccs_envp *envp, u8 *checked);
 static bool ccs_file_matches_pattern(const char *filename,
 				     const char *filename_end,
 				     const char *pattern,
@@ -233,14 +112,6 @@
 static bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
 				     const struct ccs_path_info *pattern);
 static bool ccs_path_matches_pattern2(const char *f, const char *p);
-static bool ccs_scan_bprm(struct ccs_execve *ee, const u16 argc,
-			  const struct ccs_argv *argv, const u16 envc,
-			  const struct ccs_envp *envp);
-static bool ccs_scan_exec_realpath(struct file *file,
-				   const struct ccs_name_union *ptr,
-				   const bool match);
-static bool ccs_compare_name_union(const struct ccs_path_info *name,
-				   const struct ccs_name_union *ptr);
 static bool ccs_path_matches_group(const struct ccs_path_info *pathname,
 				   const struct ccs_group *group);
 static const struct ccs_path_info *ccs_transition_type
@@ -317,14 +188,15 @@
 static int ccs_old_pivot_root_permission(struct nameidata *old_nd,
 					 struct nameidata *new_nd);
 #endif
-static int ccs_path2_perm(const u8 operation, struct dentry *dentry1,
-			  struct vfsmount *mnt1, struct dentry *dentry2,
-			  struct vfsmount *mnt2);
-static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
-				struct vfsmount *vfsmnt, unsigned long number);
-static int ccs_path_perm(const u8 operation, struct dentry *dentry,
-			 struct vfsmount *mnt);
-static int ccs_path_permission(u8 operation,
+static int ccs_path2_perm(const enum ccs_mac_index operation,
+			  struct dentry *dentry1, struct vfsmount *mnt1,
+			  struct dentry *dentry2, struct vfsmount *mnt2);
+static int ccs_path_number_perm(const enum ccs_mac_index type,
+				struct dentry *dentry, struct vfsmount *vfsmnt,
+				unsigned long number);
+static int ccs_path_perm(const enum ccs_mac_index operation,
+			 struct dentry *dentry, struct vfsmount *mnt);
+static int ccs_path_permission(enum ccs_mac_index type,
 			       const struct ccs_path_info *filename,
 			       struct ccs_obj_info *obj);
 static int ccs_start_execve(struct linux_binprm *bprm,
@@ -338,28 +210,20 @@
 static void ccs_finish_execve(int retval, struct ccs_execve *ee);
 
 #ifdef CONFIG_CCSECURITY_MISC
-static bool ccs_check_env_acl(struct ccs_request_info *r,
-			      const struct ccs_acl_info *ptr);
 static int ccs_env_perm(struct ccs_request_info *r, const char *env);
 static int ccs_environ(struct ccs_execve *ee);
 #endif
 
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 static bool __ccs_capable(const u8 operation);
-static bool ccs_check_capability_acl(struct ccs_request_info *r,
-				     const struct ccs_acl_info *ptr);
 static bool ccs_kernel_service(void);
 static int __ccs_ptrace_permission(long request, long pid);
 static int __ccs_socket_create_permission(int family, int type, int protocol);
 #endif
 
 #ifdef CONFIG_CCSECURITY_NETWORK
-static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
+static bool ccs_address_matches_group(const bool is_ipv6, const u8 *address,
 				      const struct ccs_group *group);
-static bool ccs_check_inet_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr);
-static bool ccs_check_unix_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr);
 static bool ccs_kernel_service(void);
 static int __ccs_socket_bind_permission(struct socket *sock,
 					struct sockaddr *addr, int addr_len);
@@ -389,8 +253,6 @@
 #endif
 
 #ifdef CONFIG_CCSECURITY_IPC
-static bool ccs_check_ptrace_acl(struct ccs_request_info *r,
-				 const struct ccs_acl_info *ptr);
 static int __ccs_ptrace_permission(long request, long pid);
 #endif
 
@@ -405,11 +267,6 @@
 static void ccs_unescape(unsigned char *dest);
 #endif
 
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-static bool ccs_check_task_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr);
-#endif
-
 /***** SECTION4: Standalone functions section *****/
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
@@ -680,8 +537,6 @@
 				   const struct ccs_group *group)
 {
 	struct ccs_path_group *member;
-	if (group == &ccs_group_any)
-		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
@@ -710,14 +565,11 @@
 {
 	struct ccs_number_group *member;
 	bool matched = false;
-	if (group == &ccs_group_any)
-		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
 			continue;
-		if (min > member->number.values[1] ||
-		    max < member->number.values[0])
+		if (min > member->value[1] || max < member->value[0])
 			continue;
 		matched = true;
 		break;
@@ -726,32 +578,6 @@
 }
 
 /**
- * ccs_check_use_group_acl - Do recursive permission check.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true on match, false otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static bool ccs_check_use_group_acl(struct ccs_request_info *r,
-				    struct ccs_acl_info *ptr)
-{
-	const struct ccs_use_group_acl *acl = container_of(ptr, typeof(*acl),
-							   head);
-	const struct list_head *list = &acl->group->member_list;
-	list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
-		if (!ptr->type == CCS_TYPE_USE_GROUP_ACL)
-			continue;
-		if (!ccs_check_entry(r, ptr) || !ccs_condition(r, ptr->cond))
-			continue;
-		return !acl->is_not;
-	}
-	return acl->is_not;
-}
-
-/**
  * ccs_check_entry - Do permission check.
  *
  * @r:   Pointer to "struct ccs_request_info".
@@ -764,47 +590,22 @@
 static bool ccs_check_entry(struct ccs_request_info *r,
 			    struct ccs_acl_info *ptr)
 {
-	if (ptr->is_deleted || ptr->type != r->param_type)
+	if (ptr->type == CCS_MAC_USE_GROUP) {
+		if (!ptr->is_deleted && ccs_condition(r, ptr->cond)) {
+			const struct ccs_use_group_acl *acl =
+				container_of(ptr, typeof(*acl), head);
+			const struct list_head *list =
+				&acl->group->member_list;
+			list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
+				if (ptr->type != CCS_MAC_USE_GROUP &&
+				    ccs_check_entry(r, ptr))
+					return true;
+			}
+		}
 		return false;
-	switch (r->param_type) {
-	case CCS_TYPE_EXECUTE_ACL:
-		return ccs_check_execute_acl(r, ptr);
-	case CCS_TYPE_PATH_ACL:
-		return ccs_check_path_acl(r, ptr);
-	case CCS_TYPE_PATH2_ACL:
-		return ccs_check_path2_acl(r, ptr);
-	case CCS_TYPE_PATH_NUMBER_ACL:
-		return ccs_check_path_number_acl(r, ptr);
-	case CCS_TYPE_MKDEV_ACL:
-		return ccs_check_mkdev_acl(r, ptr);
-	case CCS_TYPE_MOUNT_ACL:
-		return ccs_check_mount_acl(r, ptr);
-#ifdef CONFIG_CCSECURITY_MISC
-	case CCS_TYPE_ENV_ACL:
-		return ccs_check_env_acl(r, ptr);
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-	case CCS_TYPE_CAPABILITY_ACL:
-		return ccs_check_capability_acl(r, ptr);
-#endif
-#ifdef CONFIG_CCSECURITY_NETWORK
-	case CCS_TYPE_INET_ACL:
-		return ccs_check_inet_acl(r, ptr);
-	case CCS_TYPE_UNIX_ACL:
-		return ccs_check_unix_acl(r, ptr);
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_PTRACE_ACL:
-		return ccs_check_ptrace_acl(r, ptr);
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-	case CCS_TYPE_MANUAL_TASK_ACL:
-		return ccs_check_task_acl(r, ptr);
-#endif
-	case CCS_TYPE_USE_GROUP_ACL:
-		return ccs_check_use_group_acl(r, ptr);
 	}
-	return true;
+	return !ptr->is_deleted && ptr->type == r->type &&
+		ccs_condition(r, ptr->cond);
 }
 
 /**
@@ -819,22 +620,18 @@
 static int ccs_check_inverselist(struct ccs_request_info *r)
 {
 	struct ccs_acl_info *ptr;
-	const struct ccs_path_info *self = ccs_current_domain()->domainname;
 retry_all:
 	list_for_each_entry_srcu(ptr, &ccs_inversed_acl_list, list, &ccs_ss) {
-		struct ccs_domain_info *domain;
+		struct ccs_acl_info *ptr2;
 		int error;
-		if (ptr->mode == CCS_CONFIG_DISABLED)
+		if (ptr->is_deleted || ptr->mode == CCS_CONFIG_DISABLED)
 			continue;
 		if (!ccs_check_entry(r, ptr))
 			continue;
-		if (!ccs_condition(r, ptr->cond))
-			continue;
 		r->mode = ptr->mode;
-		list_for_each_entry_srcu(domain, &ptr->domain_list, list,
+		list_for_each_entry_srcu(ptr2, &ptr->acl_info_list, list,
 					 &ccs_ss) {
-			if (!ccs_pathcmp(self, domain->domainname) &&
-			    ccs_condition(r, domain->cond))
+			if (ccs_check_entry(r, ptr2))
 				goto next;
 		}
 		/* Did not match. */
@@ -874,8 +671,6 @@
 		list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
 			if (!ccs_check_entry(r, ptr))
 				continue;
-			if (!ccs_condition(r, ptr->cond))
-				continue;
 			r->matched_acl = ptr;
 			r->granted = true;
 			ccs_audit_log(r);
@@ -902,18 +697,16 @@
 static const struct ccs_path_info *ccs_transition_type
 (struct ccs_request_info *r)
 {
-	const struct list_head * const list = &ccs_current_namespace()->
-		default_transition_list;
+	const struct list_head * const list = &ccs_default_transition_list;
 	struct ccs_acl_info *ptr;
 	list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
 		if (ptr->is_deleted)
 			continue;
-		if (!ccs_check_execute_acl(r, ptr))
-			continue;
+		//if (!ccs_check_execute_acl(r, ptr))
+		//continue;
 		if (!ccs_condition(r, ptr->cond))
 			continue;
-		return container_of(ptr, struct ccs_execute_acl, head)->
-			transit;
+		return NULL; //container_of(ptr, struct ccs_execute_acl, head)->transit;
 	}
 	return NULL;
 }
@@ -977,7 +770,7 @@
 		domain = old_domain;
 	else if (!strcmp(domainname, "child"))
 		/* Normal domain transition. */
-		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
+		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s\\_%s",
 			 old_domain->domainname->name, exename.name);
 	else if (*domainname == '<')
 		/* Transit to the specified domain. */
@@ -987,7 +780,7 @@
 		domain = old_domain;
 	else
 		/* Transit to the child domain. */
-		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
+		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s\\_%s",
 			 old_domain->domainname->name, exename.name);
 	/*
 	 * Tell GC that I started execve().
@@ -1042,10 +835,6 @@
 			continue;
 		}
 		c = *src++;
-		if (c == '\\') {
-			*dest++ = c;
-			continue;
-		}
 		if (c < '0' || c > '3')
 			break;
 		d = *src++;
@@ -1283,14 +1072,12 @@
 	 */
 	if (ccs_current_flags() & CCS_TASK_IS_EXECUTE_HANDLER)
 		return false;
-	r->param_type = type;
+	r->type = type;
 	ccs_check_acl(r);
 	if (!r->granted)
 		return false;
-	ee->handler = container_of(r->matched_acl, struct ccs_handler_acl,
-				   head)->handler;
-	ee->transition = container_of(r->matched_acl, struct ccs_handler_acl,
-				      head)->transit;
+	ee->handler = r->handler_path;
+	ee->transition = r->transition;
 	return true;
 }
 
@@ -1393,7 +1180,7 @@
 	 * No need to call ccs_environ() for execute handler because envp[] is
 	 * moved to argv[].
 	 */
-	if (ccs_find_execute_handler(ee, CCS_TYPE_AUTO_EXECUTE_HANDLER)) {
+	if (ccs_find_execute_handler(ee, CCS_MAC_AUTO_EXECUTE_HANDLER)) {
 		retval = ccs_try_alt_exec(ee);
 		goto done;
 	}
@@ -1401,7 +1188,7 @@
 	retval = ccs_find_next_domain(ee);
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	if (retval == -EPERM &&
-	    ccs_find_execute_handler(ee, CCS_TYPE_DENIED_EXECUTE_HANDLER)) {
+	    ccs_find_execute_handler(ee, CCS_MAC_DENIED_EXECUTE_HANDLER)) {
 		retval = ccs_try_alt_exec(ee);
 		goto done;
 	}
@@ -1659,26 +1446,6 @@
 }
 
 /**
- * ccs_check_mount_acl - Check permission for path path path number operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_mount_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr)
-{
-	const struct ccs_mount_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return ccs_compare_number_union(r->param.mount.flags, &acl->flags) &&
-		ccs_compare_name_union(r->param.mount.type, &acl->fs_type) &&
-		ccs_compare_name_union(r->param.mount.dir, &acl->dir_name) &&
-		(!r->param.mount.need_dev ||
-		 ccs_compare_name_union(r->param.mount.dev, &acl->dev_name));
-}
-
-/**
  * ccs_mount_acl - Check permission for mount() operation.
  *
  * @dev_name: Name of device file. Maybe NULL.
@@ -1766,12 +1533,11 @@
 	rdev.name = requested_dev_name;
 	ccs_fill_path_info(&rdev);
 	r.type = CCS_MAC_FILE_MOUNT;
-	r.param_type = CCS_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;
+	r.param.s[0] = &rdev;
+	r.param.s[1] = &rdir;
+	r.param.s[2] = &rtype;
+	r.param.i[0] = flags;
+	r.param.i[1] = need_dev;
 	error = ccs_check_acl(&r);
 out:
 	kfree(requested_dev_name);
@@ -1859,40 +1625,6 @@
 #endif
 
 /**
- * ccs_compare_number_union - Check whether a value matches "struct ccs_number_union" or not.
- *
- * @value: Number to check.
- * @ptr:   Pointer to "struct ccs_number_union".
- *
- * Returns true if @value matches @ptr, false otherwise.
- */
-static bool ccs_compare_number_union(const unsigned long value,
-				     const struct ccs_number_union *ptr)
-{
-	if (ptr->group)
-		return ccs_number_matches_group(value, value, ptr->group) !=
-			ptr->is_not;
-	return value >= ptr->values[0] && value <= ptr->values[1];
-}
-
-/**
- * ccs_compare_name_union - Check whether a name matches "struct ccs_name_union" or not.
- *
- * @name: Pointer to "struct ccs_path_info".
- * @ptr:  Pointer to "struct ccs_name_union".
- *
- * Returns true if @name matches @ptr, false otherwise.
- */
-static bool ccs_compare_name_union(const struct ccs_path_info *name,
-				   const struct ccs_name_union *ptr)
-{
-	if (ptr->group)
-		return ccs_path_matches_group(name, ptr->group) !=
-			ptr->is_not;
-	return ccs_path_matches_pattern(name, ptr->filename);
-}
-
-/**
  * ccs_add_slash - Add trailing '/' if needed.
  *
  * @buf: Pointer to "struct ccs_path_info".
@@ -1930,115 +1662,22 @@
 }
 
 /**
- * ccs_check_execute_acl - Check permission for execute operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_execute_acl(struct ccs_request_info *r,
-				  const struct ccs_acl_info *ptr)
-{
-	const struct ccs_execute_acl *acl = container_of(ptr, typeof(*acl),
-							 head);
-	return ccs_compare_name_union(r->param.execute.program, &acl->program);
-}
-
-/**
- * ccs_check_path_acl - Check permission for path operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_path_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr)
-{
-	const struct ccs_path_acl *acl = container_of(ptr, typeof(*acl), head);
-	return (ptr->perm & (1 << r->param.path.operation)) &&
-		ccs_compare_name_union(r->param.path.filename, &acl->name);
-}
-
-/**
- * ccs_check_path_number_acl - Check permission for path number operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_path_number_acl(struct ccs_request_info *r,
-				      const struct ccs_acl_info *ptr)
-{
-	const struct ccs_path_number_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return (ptr->perm & (1 << r->param.path_number.operation)) &&
-		ccs_compare_number_union(r->param.path_number.number,
-					 &acl->number) &&
-		ccs_compare_name_union(r->param.path_number.filename,
-				       &acl->name);
-}
-
-/**
- * ccs_check_path2_acl - Check permission for path path operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_path2_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr)
-{
-	const struct ccs_path2_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return (ptr->perm & (1 << r->param.path2.operation)) &&
-		ccs_compare_name_union(r->param.path2.filename1, &acl->name1)
-		&& ccs_compare_name_union(r->param.path2.filename2,
-					  &acl->name2);
-}
-
-/**
- * ccs_check_mkdev_acl - Check permission for path number number number operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
-				const struct ccs_acl_info *ptr)
-{
-	const struct ccs_mkdev_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return (ptr->perm & (1 << r->param.mkdev.operation)) &&
-		ccs_compare_number_union(r->param.mkdev.mode, &acl->mode) &&
-		ccs_compare_number_union(r->param.mkdev.major, &acl->major) &&
-		ccs_compare_number_union(r->param.mkdev.minor, &acl->minor) &&
-		ccs_compare_name_union(r->param.mkdev.filename, &acl->name);
-}
-
-/**
  * ccs_path_permission - Check permission for path operation.
  *
- * @operation: Type of operation.
- * @filename:  Filename to check.
- * @obj:       Pointer to "struct ccs_obj_info". Maybe NULL.
+ * @type:     One of values in "enum ccs_mac_index".
+ * @filename: Filename to check.
+ * @obj:      Pointer to "struct ccs_obj_info". Maybe NULL.
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_path_permission(u8 operation,
+static int ccs_path_permission(enum ccs_mac_index type,
 			       const struct ccs_path_info *filename,
 			       struct ccs_obj_info *obj)
 {
 	struct ccs_request_info r = { };
-	r.type = ccs_p2mac[operation];
+	r.type = type;
 	r.obj = obj;
-	r.param_type = CCS_TYPE_PATH_ACL;
-	r.param.path.filename = filename;
-	r.param.path.operation = operation;
+	r.param.s[0] = filename;
 	return ccs_check_acl(&r);
 }
 
@@ -2053,10 +1692,16 @@
 static int ccs_execute_permission(struct ccs_request_info *r,
 				  const struct ccs_path_info *filename)
 {
+	struct ccs_path_info buf;
+	int error;
+	if (!ccs_get_realpath(&buf, &r->obj->path1))
+		return -ENOMEM;
 	r->type = CCS_MAC_FILE_EXECUTE;
-	r->param_type = CCS_TYPE_EXECUTE_ACL;
-	r->param.execute.program = filename;
-	return ccs_check_acl(r);
+	r->param.s[0] = &buf;
+	r->param.s[1] = filename;
+	error = ccs_check_acl(r);
+	kfree(buf.name);
+	return error;
 }
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
@@ -2145,7 +1790,7 @@
 			error = -ENOMEM;
 			goto out;
 		}
-		error = ccs_path_permission(CCS_TYPE_READ, &buf, &obj);
+		error = ccs_path_permission(CCS_MAC_FILE_READ, &buf, &obj);
 		if (error)
 			goto out;
 	}
@@ -2155,8 +1800,8 @@
 			goto out;
 		}
 		error = ccs_path_permission((flag & O_APPEND) ?
-					    CCS_TYPE_APPEND :
-					    CCS_TYPE_WRITE, &buf, &obj);
+					    CCS_MAC_FILE_APPEND :
+					    CCS_MAC_FILE_WRITE, &buf, &obj);
 	}
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
 	if (!error && (flag & O_TRUNC)) {
@@ -2164,7 +1809,7 @@
 			error = -ENOMEM;
 			goto out;
 		}
-		error = ccs_path_permission(CCS_TYPE_TRUNCATE, &buf, &obj);
+		error = ccs_path_permission(CCS_MAC_FILE_TRUNCATE, &buf, &obj);
 	}
 #endif
 out:
@@ -2192,14 +1837,14 @@
 /**
  * ccs_path_perm - Check permission for "unlink", "rmdir", "truncate", "append", "getattr", "chroot" and "unmount".
  *
- * @operation: Type of operation.
+ * @operation: One of values in "enum ccs_mac_index".
  * @dentry:    Pointer to "struct dentry".
  * @mnt:       Pointer to "struct vfsmount". Maybe NULL.
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_path_perm(const u8 operation, struct dentry *dentry,
-			 struct vfsmount *mnt)
+static int ccs_path_perm(const enum ccs_mac_index operation,
+			 struct dentry *dentry, struct vfsmount *mnt)
 {
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
@@ -2210,10 +1855,12 @@
 	if (!ccs_get_realpath(&buf, &obj.path1))
 		return -ENOMEM;
 	switch (operation) {
-	case CCS_TYPE_RMDIR:
-	case CCS_TYPE_CHROOT:
+	case CCS_MAC_FILE_RMDIR:
+	case CCS_MAC_FILE_CHROOT:
 		ccs_add_slash(&buf);
 		break;
+	default:
+		break;
 	}
 	error = ccs_path_permission(operation, &buf, &obj);
 	kfree(buf.name);
@@ -2223,7 +1870,7 @@
 /**
  * ccs_mkdev_perm - Check permission for "mkblock" and "mkchar".
  *
- * @operation: Type of operation. (CCS_TYPE_MKCHAR or CCS_TYPE_MKBLOCK)
+ * @operation: Type of operation. (CCS_MAC_FILE_MKCHAR or CCS_MAC_FILE_MKBLOCK)
  * @dentry:    Pointer to "struct dentry".
  * @mnt:       Pointer to "struct vfsmount". Maybe NULL.
  * @mode:      Create mode.
@@ -2249,14 +1896,12 @@
 #endif
 	{
 		struct ccs_request_info r = { };
-		r.type = ccs_pnnn2mac[operation];
+		r.type = operation;
 		r.obj = &obj;
-		r.param_type = CCS_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);
+		r.param.s[0] = &buf;
+		r.param.i[0] = mode;
+		r.param.i[1] = MAJOR(dev);
+		r.param.i[2] = MINOR(dev);
 		error = ccs_check_acl(&r);
 	}
 	kfree(buf.name);
@@ -2266,7 +1911,7 @@
 /**
  * ccs_path2_perm - Check permission for "rename", "link" and "pivot_root".
  *
- * @operation: Type of operation.
+ * @operation: One of values in "enum ccs_mac_index".
  * @dentry1:   Pointer to "struct dentry".
  * @mnt1:      Pointer to "struct vfsmount". Maybe NULL.
  * @dentry2:   Pointer to "struct dentry".
@@ -2274,9 +1919,9 @@
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_path2_perm(const u8 operation, struct dentry *dentry1,
-			  struct vfsmount *mnt1, struct dentry *dentry2,
-			  struct vfsmount *mnt2)
+static int ccs_path2_perm(const enum ccs_mac_index operation,
+			  struct dentry *dentry1, struct vfsmount *mnt1,
+			  struct dentry *dentry2, struct vfsmount *mnt2)
 {
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry1,
@@ -2295,24 +1940,24 @@
 		return -ENOMEM;
 	}
 	switch (operation) {
-	case CCS_TYPE_RENAME:
-	case CCS_TYPE_LINK:
+	case CCS_MAC_FILE_RENAME:
+	case CCS_MAC_FILE_LINK:
 		if (!dentry1->d_inode || !S_ISDIR(dentry1->d_inode->i_mode))
 			break;
 		/* fall through */
-	case CCS_TYPE_PIVOT_ROOT:
+	case CCS_MAC_FILE_PIVOT_ROOT:
 		ccs_add_slash(&buf1);
 		ccs_add_slash(&buf2);
 		break;
+	default:
+		break;
 	}
 	{
 		struct ccs_request_info r = { };
-		r.type = ccs_pp2mac[operation];
+		r.type = operation;
 		r.obj = &obj;
-		r.param_type = CCS_TYPE_PATH2_ACL;
-		r.param.path2.operation = operation;
-		r.param.path2.filename1 = &buf1;
-		r.param.path2.filename2 = &buf2;
+		r.param.s[0] = &buf1;
+		r.param.s[1] = &buf2;
 		error = ccs_check_acl(&r);
 	}
 	kfree(buf1.name);
@@ -2352,10 +1997,8 @@
 		struct ccs_request_info r = { };
 		r.type = CCS_MAC_FILE_SYMLINK;
 		r.obj = &obj;
-		r.param_type = CCS_TYPE_PATH2_ACL;
-		r.param.path2.operation = CCS_TYPE_SYMLINK;
-		r.param.path2.filename1 = &buf1;
-		r.param.path2.filename2 = &buf2;
+		r.param.s[0] = &buf1;
+		r.param.s[1] = &buf2;
 		error = ccs_check_acl(&r);
 	}
 	kfree(buf1.name);
@@ -2366,15 +2009,16 @@
 /**
  * ccs_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
  *
- * @type:   Type of operation.
+ * @type:   One of values in "enum ccs_mac_index".
  * @dentry: Pointer to "struct dentry".
  * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
  * @number: Number.
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
-				struct vfsmount *vfsmnt, unsigned long number)
+static int ccs_path_number_perm(const enum ccs_mac_index type,
+				struct dentry *dentry, struct vfsmount *vfsmnt,
+				unsigned long number)
 {
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
@@ -2387,16 +2031,14 @@
 	ccs_check_auto_domain_transition();
 	if (!ccs_get_realpath(&buf, &obj.path1))
 		return -ENOMEM;
-	if (type == CCS_TYPE_MKDIR)
+	if (type == CCS_MAC_FILE_MKDIR)
 		ccs_add_slash(&buf);
 	{
 		struct ccs_request_info r = { };
-		r.type = ccs_pn2mac[type];
+		r.type = type;
 		r.obj = &obj;
-		r.param_type = CCS_TYPE_PATH_NUMBER_ACL;
-		r.param.path_number.operation = type;
-		r.param.path_number.filename = &buf;
-		r.param.path_number.number = number;
+		r.param.s[0] = &buf;
+		r.param.i[0] = number;
 		error = ccs_check_acl(&r);
 	}
 	kfree(buf.name);
@@ -2415,7 +2057,7 @@
 static int __ccs_ioctl_permission(struct file *filp, unsigned int cmd,
 				  unsigned long arg)
 {
-	return ccs_path_number_perm(CCS_TYPE_IOCTL, filp->f_dentry,
+	return ccs_path_number_perm(CCS_MAC_FILE_IOCTL, filp->f_dentry,
 				    filp->f_vfsmnt, cmd);
 }
 
@@ -2433,7 +2075,7 @@
 {
 	if (mode == (mode_t) -1)
 		return 0;
-	return ccs_path_number_perm(CCS_TYPE_CHMOD, dentry, vfsmnt,
+	return ccs_path_number_perm(CCS_MAC_FILE_CHMOD, dentry, vfsmnt,
 				    mode & S_IALLUGO);
 }
 
@@ -2455,11 +2097,11 @@
 	if (user == (uid_t) -1 && group == (gid_t) -1)
 		return 0;
 	if (user != (uid_t) -1)
-		error = ccs_path_number_perm(CCS_TYPE_CHOWN, dentry, vfsmnt,
-					     user);
+		error = ccs_path_number_perm(CCS_MAC_FILE_CHOWN, dentry,
+					     vfsmnt, user);
 	if (!error && group != (gid_t) -1)
-		error = ccs_path_number_perm(CCS_TYPE_CHGRP, dentry, vfsmnt,
-					     group);
+		error = ccs_path_number_perm(CCS_MAC_FILE_CHGRP, dentry,
+					     vfsmnt, group);
 	return error;
 }
 
@@ -2500,7 +2142,7 @@
 static int __ccs_pivot_root_permission(struct path *old_path,
 				       struct path *new_path)
 {
-	return ccs_path2_perm(CCS_TYPE_PIVOT_ROOT, new_path->dentry,
+	return ccs_path2_perm(CCS_MAC_FILE_PIVOT_ROOT, new_path->dentry,
 			      new_path->mnt, old_path->dentry, old_path->mnt);
 }
 
@@ -2513,7 +2155,7 @@
  */
 static int __ccs_chroot_permission(struct path *path)
 {
-	return ccs_path_perm(CCS_TYPE_CHROOT, path->dentry, path->mnt);
+	return ccs_path_perm(CCS_MAC_FILE_CHROOT, path->dentry, path->mnt);
 }
 
 /**
@@ -2526,7 +2168,7 @@
  */
 static int __ccs_umount_permission(struct vfsmount *mnt, int flags)
 {
-	return ccs_path_perm(CCS_TYPE_UMOUNT, mnt->mnt_root, mnt);
+	return ccs_path_perm(CCS_MAC_FILE_UMOUNT, mnt->mnt_root, mnt);
 }
 
 /**
@@ -2546,24 +2188,24 @@
 	const unsigned int perm = mode & S_IALLUGO;
 	switch (mode & S_IFMT) {
 	case S_IFCHR:
-		error = ccs_mkdev_perm(CCS_TYPE_MKCHAR, dentry, mnt, perm,
+		error = ccs_mkdev_perm(CCS_MAC_FILE_MKCHAR, dentry, mnt, perm,
 				       dev);
 		break;
 	case S_IFBLK:
-		error = ccs_mkdev_perm(CCS_TYPE_MKBLOCK, dentry, mnt, perm,
+		error = ccs_mkdev_perm(CCS_MAC_FILE_MKBLOCK, dentry, mnt, perm,
 				       dev);
 		break;
 	case S_IFIFO:
-		error = ccs_path_number_perm(CCS_TYPE_MKFIFO, dentry, mnt,
+		error = ccs_path_number_perm(CCS_MAC_FILE_MKFIFO, dentry, mnt,
 					     perm);
 		break;
 	case S_IFSOCK:
-		error = ccs_path_number_perm(CCS_TYPE_MKSOCK, dentry, mnt,
+		error = ccs_path_number_perm(CCS_MAC_FILE_MKSOCK, dentry, mnt,
 					     perm);
 		break;
 	case 0:
 	case S_IFREG:
-		error = ccs_path_number_perm(CCS_TYPE_CREATE, dentry, mnt,
+		error = ccs_path_number_perm(CCS_MAC_FILE_CREATE, dentry, mnt,
 					     perm);
 		break;
 	}
@@ -2582,7 +2224,7 @@
 static int __ccs_mkdir_permission(struct dentry *dentry, struct vfsmount *mnt,
 				  unsigned int mode)
 {
-	return ccs_path_number_perm(CCS_TYPE_MKDIR, dentry, mnt, mode);
+	return ccs_path_number_perm(CCS_MAC_FILE_MKDIR, dentry, mnt, mode);
 }
 
 /**
@@ -2595,7 +2237,7 @@
  */
 static int __ccs_rmdir_permission(struct dentry *dentry, struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_RMDIR, dentry, mnt);
+	return ccs_path_perm(CCS_MAC_FILE_RMDIR, dentry, mnt);
 }
 
 /**
@@ -2608,7 +2250,7 @@
  */
 static int __ccs_unlink_permission(struct dentry *dentry, struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_UNLINK, dentry, mnt);
+	return ccs_path_perm(CCS_MAC_FILE_UNLINK, dentry, mnt);
 }
 
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -2624,7 +2266,7 @@
 static int __ccs_getattr_permission(struct vfsmount *mnt,
 				    struct dentry *dentry)
 {
-	return ccs_path_perm(CCS_TYPE_GETATTR, dentry, mnt);
+	return ccs_path_perm(CCS_MAC_FILE_GETATTR, dentry, mnt);
 }
 
 #endif
@@ -2640,7 +2282,7 @@
 static int __ccs_truncate_permission(struct dentry *dentry,
 				     struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_TRUNCATE, dentry, mnt);
+	return ccs_path_perm(CCS_MAC_FILE_TRUNCATE, dentry, mnt);
 }
 
 /**
@@ -2656,7 +2298,7 @@
 				   struct dentry *new_dentry,
 				   struct vfsmount *mnt)
 {
-	return ccs_path2_perm(CCS_TYPE_RENAME, old_dentry, mnt, new_dentry,
+	return ccs_path2_perm(CCS_MAC_FILE_RENAME, old_dentry, mnt, new_dentry,
 			      mnt);
 }
 
@@ -2673,7 +2315,8 @@
 				 struct dentry *new_dentry,
 				 struct vfsmount *mnt)
 {
-	return ccs_path2_perm(CCS_TYPE_LINK, old_dentry, mnt, new_dentry, mnt);
+	return ccs_path2_perm(CCS_MAC_FILE_LINK, old_dentry, mnt, new_dentry,
+			      mnt);
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
@@ -2792,11 +2435,12 @@
 			goto out;
 		ccs_fill_path_info(&buf);
 		if (op & MAY_READ)
-			error = ccs_path_permission(CCS_TYPE_READ, &buf, NULL);
+			error = ccs_path_permission(CCS_MAC_FILE_READ, &buf,
+						    NULL);
 		else
 			error = 0;
 		if (!error && (op & MAY_WRITE))
-			error = ccs_path_permission(CCS_TYPE_WRITE, &buf,
+			error = ccs_path_permission(CCS_MAC_FILE_WRITE, &buf,
 						    NULL);
 		kfree(buf.name);
 		if (error)
@@ -2814,11 +2458,12 @@
 			goto out;
 		ccs_fill_path_info(&buf);
 		if (op & MAY_READ)
-			error = ccs_path_permission(CCS_TYPE_READ, &buf, NULL);
+			error = ccs_path_permission(CCS_MAC_FILE_READ, &buf,
+						    NULL);
 		else
 			error = 0;
 		if (!error && (op & MAY_WRITE))
-			error = ccs_path_permission(CCS_TYPE_WRITE, &buf,
+			error = ccs_path_permission(CCS_MAC_FILE_WRITE, &buf,
 						    NULL);
 		kfree(buf.name);
 		goto out;
@@ -2877,22 +2522,20 @@
  *
  * Caller holds ccs_read_lock().
  */
-static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
+static bool ccs_address_matches_group(const bool is_ipv6, const u8 *address,
 				      const struct ccs_group *group)
 {
 	struct ccs_address_group *member;
 	bool matched = false;
 	const u8 size = is_ipv6 ? 16 : 4;
-	if (group == &ccs_group_any)
-		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
 			continue;
-		if (member->address.is_ipv6 != is_ipv6)
+		if (member->is_ipv6 != is_ipv6)
 			continue;
-		if (memcmp(&member->address.ip[0], address, size) > 0 ||
-		    memcmp(address, &member->address.ip[1], size) > 0)
+		if (memcmp(&member->ip[0], address, size) > 0 ||
+		    memcmp(address, &member->ip[1], size) > 0)
 			continue;
 		matched = true;
 		break;
@@ -2901,51 +2544,6 @@
 }
 
 /**
- * ccs_check_inet_acl - Check permission for inet domain socket operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_inet_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr)
-{
-	const struct ccs_inet_acl *acl = container_of(ptr, typeof(*acl), head);
-	const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
-	if (!(ptr->perm & (1 << r->param.inet_network.operation)) ||
-	    !ccs_compare_number_union(r->param.inet_network.port, &acl->port))
-		return false;
-	if (acl->address.group)
-		return ccs_address_matches_group(r->param.inet_network.is_ipv6,
-						 r->param.inet_network.address,
-						 acl->address.group)
-			!= acl->address.is_not;
-	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;
-}
-
-/**
- * ccs_check_unix_acl - Check permission for unix domain socket operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_unix_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr)
-{
-	const struct ccs_unix_acl *acl = container_of(ptr, typeof(*acl), head);
-	return (ptr->perm & (1 << r->param.unix_network.operation)) &&
-		ccs_compare_name_union(r->param.unix_network.address,
-				       &acl->name);
-}
-
-/**
  * ccs_inet_entry - Check permission for INET network operation.
  *
  * @address: Pointer to "struct ccs_addr_info".
@@ -2954,26 +2552,20 @@
  */
 static int ccs_inet_entry(const struct ccs_addr_info *address)
 {
-	const u8 type = ccs_inet2mac[address->protocol][address->operation];
+	struct ccs_request_info r = { };
 	ccs_check_auto_domain_transition();
-	if (type) {
-		struct ccs_request_info r = { };
-		r.type = type;
-		r.param_type = CCS_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);
-		r.dont_sleep_on_enforce_error =
-			address->operation == CCS_NETWORK_ACCEPT
+	r.type = address->operation;
+	r.param.is_ipv6 = address->inet.is_ipv6;
+	r.param.ip = address->inet.address;
+	r.param.i[0] = ntohs(address->inet.port);
+	r.dont_sleep_on_enforce_error =
+		r.type == CCS_MAC_NETWORK_INET_STREAM_ACCEPT
 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-			|| address->operation == CCS_NETWORK_RECV
+		|| r.type == CCS_MAC_NETWORK_INET_DGRAM_RECV ||
+		r.type == CCS_MAC_NETWORK_INET_RAW_RECV;
 #endif
-			;
-		return ccs_check_acl(&r);
-	}
-	return 0;
+		;
+	return ccs_check_acl(&r);
 }
 
 /**
@@ -2996,7 +2588,7 @@
 		if (addr_len < SIN6_LEN_RFC2133)
 			goto skip;
 		i->is_ipv6 = true;
-		i->address = (u32 *)
+		i->address =
 			((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
 		i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
 		break;
@@ -3004,13 +2596,15 @@
 		if (addr_len < sizeof(struct sockaddr_in))
 			goto skip;
 		i->is_ipv6 = false;
-		i->address = (u32 *) &((struct sockaddr_in *) addr)->sin_addr;
+		i->address = (u8 *) &((struct sockaddr_in *) addr)->sin_addr;
 		i->port = ((struct sockaddr_in *) addr)->sin_port;
 		break;
 	default:
 		goto skip;
 	}
-	if (address->protocol == SOCK_RAW)
+	if (address->operation == CCS_MAC_NETWORK_INET_RAW_BIND ||
+	    address->operation == CCS_MAC_NETWORK_INET_RAW_SEND ||
+	    address->operation == CCS_MAC_NETWORK_INET_RAW_RECV)
 		i->port = htons(port);
 	return ccs_inet_entry(address);
 skip:
@@ -3026,39 +2620,34 @@
  */
 static int ccs_unix_entry(const struct ccs_addr_info *address)
 {
-	int error = 0;
-	const u8 type = ccs_unix2mac[address->protocol][address->operation];
-	if (type) {
-		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 = ccs_encode2(buf, len);
-		if (buf) {
-			struct ccs_path_info addr;
-			struct ccs_request_info r = { };
-			addr.name = buf;
-			ccs_fill_path_info(&addr);
-			r.type = type;
-			r.param_type = CCS_TYPE_UNIX_ACL;
-			r.param.unix_network.protocol = address->protocol;
-			r.param.unix_network.operation = address->operation;
-			r.param.unix_network.address = &addr;
-			r.dont_sleep_on_enforce_error =
-				address->operation == CCS_NETWORK_ACCEPT
+	int error;
+	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 = ccs_encode2(buf, len);
+	if (buf) {
+		struct ccs_path_info addr;
+		struct ccs_request_info r = { };
+		addr.name = buf;
+		ccs_fill_path_info(&addr);
+		r.type = address->operation;
+		r.param.s[0] = &addr;
+		r.dont_sleep_on_enforce_error =
+			r.type == CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT ||
+			r.type == CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT
 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
-				|| address->operation == CCS_NETWORK_RECV
+			|| r.type == CCS_MAC_NETWORK_UNIX_DGRAM_RECV
 #endif
-				;
-			error = ccs_check_acl(&r);
-			kfree(buf);
-		} else
-			error = -ENOMEM;
-	}
+			;
+		error = ccs_check_acl(&r);
+		kfree(buf);
+	} else
+		error = -ENOMEM;
 	return error;
 }
 
@@ -3128,8 +2717,12 @@
 		if (error)
 			return error;
 	}
-	address.protocol = type;
-	address.operation = CCS_NETWORK_LISTEN;
+	if (family == PF_INET || family == PF_INET6)
+		address.operation = CCS_MAC_NETWORK_INET_STREAM_LISTEN;
+	else if (type == SOCK_STREAM)
+		address.operation = CCS_MAC_NETWORK_UNIX_STREAM_LISTEN;
+	else
+		address.operation = CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN;
 	if (family == PF_UNIX)
 		return ccs_check_unix_address((struct sockaddr *) &addr,
 					      addr_len, &address);
@@ -3151,18 +2744,24 @@
 {
 	struct ccs_addr_info address;
 	const u8 family = ccs_sock_family(sock->sk);
-	const unsigned int type = sock->type;
 	if (!family)
 		return 0;
-	address.protocol = type;
-	switch (type) {
+	switch (sock->type) {
 	case SOCK_DGRAM:
+		address.operation = family == PF_UNIX ?
+			CCS_MAC_NETWORK_UNIX_DGRAM_SEND :
+			CCS_MAC_NETWORK_INET_DGRAM_SEND;
+		break;
 	case SOCK_RAW:
-		address.operation = CCS_NETWORK_SEND;
+		address.operation = CCS_MAC_NETWORK_INET_RAW_SEND;
 		break;
 	case SOCK_STREAM:
+		address.operation = family == PF_UNIX ?
+			CCS_MAC_NETWORK_UNIX_STREAM_CONNECT :
+			CCS_MAC_NETWORK_INET_STREAM_CONNECT;
+		break;
 	case SOCK_SEQPACKET:
-		address.operation = CCS_NETWORK_CONNECT;
+		address.operation = CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT;
 		break;
 	default:
 		return 0;
@@ -3192,11 +2791,20 @@
 		return 0;
 	switch (type) {
 	case SOCK_STREAM:
+		address.operation = family == PF_UNIX ?
+			CCS_MAC_NETWORK_UNIX_STREAM_BIND :
+			CCS_MAC_NETWORK_INET_STREAM_BIND;
+		break;
 	case SOCK_DGRAM:
+		address.operation = family == PF_UNIX ?
+			CCS_MAC_NETWORK_UNIX_DGRAM_BIND :
+			CCS_MAC_NETWORK_INET_DGRAM_BIND;
+		break;
 	case SOCK_RAW:
+		address.operation = CCS_MAC_NETWORK_INET_RAW_BIND;
+		break;
 	case SOCK_SEQPACKET:
-		address.protocol = type;
-		address.operation = CCS_NETWORK_BIND;
+		address.operation = CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND;
 		break;
 	default:
 		return 0;
@@ -3225,9 +2833,13 @@
 	if (!msg->msg_name || !family ||
 	    (type != SOCK_DGRAM && type != SOCK_RAW))
 		return 0;
-	address.protocol = type;
-	address.operation = CCS_NETWORK_SEND;
 	if (family == PF_UNIX)
+		address.operation = CCS_MAC_NETWORK_UNIX_DGRAM_SEND;
+	else if (type == SOCK_DGRAM)
+		address.operation = CCS_MAC_NETWORK_INET_DGRAM_SEND;
+	else
+		address.operation = CCS_MAC_NETWORK_INET_RAW_SEND;
+	if (family == PF_UNIX)
 		return ccs_check_unix_address((struct sockaddr *)
 					      msg->msg_name, msg->msg_namelen,
 					      &address);
@@ -3261,8 +2873,12 @@
 		if (error)
 			return error;
 	}
-	address.protocol = type;
-	address.operation = CCS_NETWORK_ACCEPT;
+	if (family == PF_INET || family == PF_INET6)
+		address.operation = CCS_MAC_NETWORK_INET_STREAM_ACCEPT;
+	else if (type == SOCK_STREAM)
+		address.operation = CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT;
+	else
+		address.operation = CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT;
 	if (family == PF_UNIX)
 		return ccs_check_unix_address((struct sockaddr *) &addr,
 					      addr_len, &address);
@@ -3288,17 +2904,14 @@
 	const u8 family = ccs_sock_family(sk);
 	const unsigned int type = sk->sk_type;
 	struct sockaddr_storage addr;
-	if (!family)
+	if (!family || (type != SOCK_DGRAM && type != SOCK_RAW))
 		return 0;
-	switch (type) {
-	case SOCK_DGRAM:
-	case SOCK_RAW:
-		address.protocol = type;
-		break;
-	default:
-		return 0;
-	}
-	address.operation = CCS_NETWORK_RECV;
+	if (family == PF_UNIX)
+		address.operation = CCS_MAC_NETWORK_UNIX_DGRAM_RECV;
+	else if (type == SOCK_DGRAM)
+		address.operation = CCS_MAC_NETWORK_INET_DGRAM_RECV;
+	else
+		address.operation = CCS_MAC_NETWORK_INET_RAW_RECV;
 	switch (family) {
 	case PF_INET6:
 		{
@@ -3309,7 +2922,7 @@
 				ipv6_addr_set(sin6, 0, 0, htonl(0xffff),
 					      ip_hdr(skb)->saddr);
 			else
-				ipv6_addr_copy(sin6, &ipv6_hdr(skb)->saddr);
+				*sin6 = ipv6_hdr(skb)->saddr;
 			break;
 		}
 	case PF_INET:
@@ -3341,7 +2954,7 @@
 			return 0;
 		}
 	}
-	address.inet.address = (u32 *) &addr;
+	address.inet.address = (u8 *) &addr;
 	if (type == SOCK_DGRAM)
 		address.inet.port = udp_hdr(skb)->source;
 	else
@@ -3399,22 +3012,6 @@
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 
 /**
- * ccs_check_capability_acl - Check permission for capability operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_capability_acl(struct ccs_request_info *r,
-				     const struct ccs_acl_info *ptr)
-{
-	const struct ccs_capability_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return acl->operation == r->param.capability.operation;
-}
-
-/**
  * ccs_capable - Check permission for capability.
  *
  * @operation: Type of operation.
@@ -3425,8 +3022,6 @@
 {
 	struct ccs_request_info r = { };
 	r.type = ccs_c2mac[operation];
-	r.param_type = CCS_TYPE_CAPABILITY_ACL;
-	r.param.capability.operation = operation;
 	return !ccs_check_acl(&r);
 }
 
@@ -3455,24 +3050,6 @@
 #ifdef CONFIG_CCSECURITY_IPC
 
 /**
- * ccs_check_ptrace_acl - Check permission for ptrace operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_ptrace_acl(struct ccs_request_info *r,
-				 const struct ccs_acl_info *ptr)
-{
-	const struct ccs_ptrace_acl *acl =
-		container_of(ptr, typeof(*acl), head);
-	return ccs_compare_number_union(r->param.ptrace.request,
-					&acl->request) &&
-		!strcmp(acl->domainname->name, r->param.ptrace.domainname);
-}
-
-/**
  * __ccs_ptrace_permission - Check permission for ptrace().
  *
  * @request: Command number.
@@ -3502,9 +3079,8 @@
 			goto out;
 	}
 	r.type = CCS_MAC_PTRACE;
-	r.param_type = CCS_TYPE_PTRACE_ACL;
-	r.param.ptrace.request = request;
-	r.param.ptrace.domainname = dest->domainname->name;
+	r.param.i[0] = request;
+	r.param.s[0] = dest->domainname;
 	error = ccs_check_acl(&r);
 out:
 	ccs_read_unlock(idx);
@@ -3516,21 +3092,6 @@
 #ifdef CONFIG_CCSECURITY_MISC
 
 /**
- * ccs_check_env_acl - Check permission for environment variable's name.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_env_acl(struct ccs_request_info *r,
-			      const struct ccs_acl_info *ptr)
-{
-	const struct ccs_env_acl *acl = container_of(ptr, typeof(*acl), head);
-	return ccs_compare_name_union(r->param.environ.name, &acl->env);
-}
-
-/**
  * ccs_env_perm - Check permission for environment variable's name.
  *
  * @r:   Pointer to "struct ccs_request_info".
@@ -3546,8 +3107,7 @@
 	environ.name = env;
 	ccs_fill_path_info(&environ);
 	r->type = CCS_MAC_ENVIRON;
-	r->param_type = CCS_TYPE_ENV_ACL;
-	r->param.environ.name = &environ;
+	r->param.s[0] = &environ;
 	return ccs_check_acl(r);
 }
 
@@ -3592,10 +3152,7 @@
 			if (c && arg_len < CCS_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) {
+				} else if (c > ' ' && c < 127 && c != '\\') {
 					arg_ptr[arg_len++] = c;
 				} else {
 					arg_ptr[arg_len++] = '\\';
@@ -3630,94 +3187,74 @@
 #endif
 
 /**
- * ccs_argv - Check argv[] in "struct linux_binbrm".
+ * ccs_check_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 ccs_argv".
- * @checked: Set to true if @argv[@index] was found.
+ * @ee:     Pointer to "struct ccs_execve".
+ * @index:  Index number to check.
+ * @value:  Poiner to "struct ccs_path_info".
+ * @is_not: True if negative match, false otherwise.
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_argv(const unsigned int index, const char *arg_ptr,
-		     const int argc, const struct ccs_argv *argv,
-		     u8 *checked)
+static bool ccs_check_argv(struct ccs_execve *ee, unsigned long index,
+			   const struct ccs_path_info *value,
+			   const bool is_not)
 {
-	int i;
+	struct linux_binprm *bprm = ee->bprm;
+	struct ccs_page_dump *dump = &ee->dump;
+	char *arg_ptr = ee->tmp;
+	int arg_len = 0;
+	unsigned long pos = bprm->p;
+	int offset = pos % PAGE_SIZE;
 	struct ccs_path_info arg;
-	arg.name = arg_ptr;
-	for (i = 0; i < argc; argv++, checked++, i++) {
-		bool result;
-		if (index != argv->index)
-			continue;
-		*checked = 1;
-		ccs_fill_path_info(&arg);
-		result = ccs_path_matches_pattern(&arg, argv->value);
-		if (argv->is_not)
-			result = !result;
-		if (!result)
+	if (index > bprm->argc)
+		return false;
+	while (1) {
+		if (!ccs_dump_page(bprm, pos, dump))
 			return false;
-	}
-	return true;
-}
-
-/**
- * ccs_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 ccs_envp".
- * @checked:   Set to true if @envp[@env_name] was found.
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_envp(const char *env_name, const char *env_value,
-		     const int envc, const struct ccs_envp *envp,
-		     u8 *checked)
-{
-	int i;
-	struct ccs_path_info name;
-	struct ccs_path_info value;
-	name.name = env_name;
-	ccs_fill_path_info(&name);
-	value.name = env_value;
-	ccs_fill_path_info(&value);
-	for (i = 0; i < envc; envp++, checked++, i++) {
-		bool result;
-		if (!ccs_path_matches_pattern(&name, envp->name))
-			continue;
-		*checked = 1;
-		if (envp->value) {
-			result = ccs_path_matches_pattern(&value, envp->value);
-			if (envp->is_not)
-				result = !result;
-		} else {
-			result = true;
-			if (!envp->is_not)
-				result = !result;
+		pos += PAGE_SIZE - offset;
+		while (offset < PAGE_SIZE) {
+			const unsigned char c = dump->data[offset++];
+			if (index) {
+				if (!c)
+					index--;
+				continue;
+			}
+			if (c && arg_len < CCS_EXEC_TMPSIZE - 10) {
+				if (c > ' ' && c < 127 && c != '\\') {
+					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';
+				}
+				continue;
+			}
+			arg_ptr[arg_len] = '\0';
+			arg.name = arg_ptr;
+			ccs_fill_path_info(&arg);
+			return ccs_path_matches_pattern(&arg, value) != is_not;
 		}
-		if (!result)
-			return false;
+		offset = 0;
 	}
-	return true;
 }
 
 /**
- * ccs_scan_bprm - Scan "struct linux_binprm".
+ * ccs_check_envp - Check envp[] in "struct linux_binbrm".
  *
- * @ee:   Pointer to "struct ccs_execve".
- * @argc: Length of @argc.
- * @argv: Pointer to "struct ccs_argv".
- * @envc: Length of @envp.
- * @envp: Poiner to "struct ccs_envp".
+ * @ee:     Pointer to "struct ccs_execve".
+ * @name:   Pointer to "struct ccs_path_info".
+ * @value:  Pointer to "struct ccs_path_info". Maybe NULL.
+ * @is_not: True if negative match, false othwerwise.
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_scan_bprm(struct ccs_execve *ee,
-			  const u16 argc, const struct ccs_argv *argv,
-			  const u16 envc, const struct ccs_envp *envp)
+static bool ccs_check_envp(struct ccs_execve *ee,
+			   const struct ccs_path_info *name,
+			   const struct ccs_path_info *value,
+			   const bool is_not)
 {
 	struct linux_binprm *bprm = ee->bprm;
 	struct ccs_page_dump *dump = &ee->dump;
@@ -3727,32 +3264,23 @@
 	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, CCS_GFP_FLAGS);
-		if (!checked)
+	bool result = !value == !is_not;
+	struct ccs_path_info n;
+	struct ccs_path_info v;
+	char *cp;
+	while (envp_count) {
+		if (!ccs_dump_page(bprm, pos, dump))
 			return false;
-	}
-	while (argv_count || envp_count) {
-		if (!ccs_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++];
+		while (envp_count && offset < PAGE_SIZE) {
+			const unsigned char c = dump->data[offset++];
+			if (argv_count) {
+				if (!c)
+					argv_count--;
+				continue;
+			}
 			if (c && arg_len < CCS_EXEC_TMPSIZE - 10) {
-				if (c == '\\') {
-					arg_ptr[arg_len++] = '\\';
-					arg_ptr[arg_len++] = '\\';
-				} else if (c > ' ' && c < 127) {
+				if (c > ' ' && c < 127 && c != '\\') {
 					arg_ptr[arg_len++] = c;
 				} else {
 					arg_ptr[arg_len++] = '\\';
@@ -3766,107 +3294,34 @@
 			}
 			if (c)
 				continue;
-			/* Check. */
-			if (argv_count) {
-				if (!ccs_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 (!ccs_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])
+			envp_count--;
+			/* Check. */
+			cp = strchr(arg_ptr, '=');
+			if (!cp)
 				continue;
-			/*
-			 * Return true only if all unchecked indexes in
-			 * bprm->argv[] are not matched.
-			 */
-			if (argv[i].is_not)
+			*cp++ = '\0';
+			n.name = arg_ptr;
+			ccs_fill_path_info(&n);
+			if (!ccs_path_matches_pattern(&n, name))
 				continue;
-			result = false;
-			break;
-		}
-		for (i = 0; i < envc; envp++, i++) {
-			if (checked[argc + i])
+			result = true;
+			if (!value) {
+				if (!is_not)
+					return false;
 				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;
+			}
+			v.name = cp;
+			ccs_fill_path_info(&v);
+			if (ccs_path_matches_pattern(&v, value) != is_not)
+				return false;
 		}
+		offset = 0;
 	}
-	if (checked != local_checked)
-		kfree(checked);
 	return result;
 }
 
 /**
- * ccs_scan_exec_realpath - Check "exec.realpath" parameter of "struct ccs_condition".
- *
- * @file:  Pointer to "struct file".
- * @ptr:   Pointer to "struct ccs_name_union".
- * @match: True if "exec.realpath=", false if "exec.realpath!=".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_scan_exec_realpath(struct file *file,
-				   const struct ccs_name_union *ptr,
-				   const bool match)
-{
-	bool result;
-	struct ccs_path_info exe;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-	struct path path;
-#endif
-	if (!file)
-		return false;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
-	exe.name = ccs_realpath(&file->f_path);
-#else
-	path.mnt = file->f_vfsmnt;
-	path.dentry = file->f_dentry;
-	exe.name = ccs_realpath(&path);
-#endif
-	if (!exe.name)
-		return false;
-	ccs_fill_path_info(&exe);
-	result = ccs_compare_name_union(&exe, ptr);
-	kfree(exe.name);
-	return result == match;
-}
-
-/**
  * ccs_get_attributes - Revalidate "struct inode".
  *
  * @obj: Pointer to "struct ccs_obj_info".
@@ -3918,11 +3373,264 @@
 			stat->rdev = inode->i_rdev;
 			obj->stat_valid[i] = true;
 		}
-		if (i & 1) /* i == CCS_PATH1_PARENT || i == CCS_PATH2_PARENT */
+		if (i & 1) /* parent directory */
 			dput(dentry);
 	}
 }
 
+enum ccs_arg_type {
+	CCS_ARG_TYPE_NUMBER,
+	CCS_ARG_TYPE_NAME,
+	CCS_ARG_TYPE_DOMAINNAME,
+	CCS_ARG_TYPE_GROUP,
+	CCS_ARG_TYPE_BITOP,
+	CCS_ARG_TYPE_IPV6ADDR,
+} __packed;
+
+struct ccs_cond_arg {
+	enum ccs_arg_type type;
+	unsigned long value[2];
+	const struct ccs_path_info *name;
+	const struct ccs_path_info *domainname;
+	const struct ccs_group *group;
+	struct in6_addr ipv6[2];
+};
+
+static bool ccs_cond2arg(struct ccs_cond_arg *arg,
+			 const enum ccs_conditions_index cmd,
+			 const union ccs_condition_element **condp,
+			 struct ccs_request_info *r)
+{
+	struct ccs_mini_stat *stat;
+	unsigned long value;
+	struct ccs_obj_info *obj = r->obj;
+	const struct linux_binprm *bprm = r->ee ? r->ee->bprm : NULL;
+	const struct ccs_request_param *param = &r->param;
+	arg->type = CCS_ARG_TYPE_NUMBER;
+	switch (cmd) {
+	case CCS_SELF_UID:
+		value = current_uid();
+		break;
+	case CCS_SELF_EUID:
+		value = current_euid();
+		break;
+	case CCS_SELF_SUID:
+		value = current_suid();
+		break;
+	case CCS_SELF_FSUID:
+		value = current_fsuid();
+		break;
+	case CCS_SELF_GID:
+		value = current_gid();
+		break;
+	case CCS_SELF_EGID:
+		value = current_egid();
+		break;
+	case CCS_SELF_SGID:
+		value = current_sgid();
+		break;
+	case CCS_SELF_FSGID:
+		value = current_fsgid();
+		break;
+	case CCS_SELF_PID:
+		value = ccs_sys_getpid();
+		break;
+	case CCS_SELF_PPID:
+		value = ccs_sys_getppid();
+		break;
+	case CCS_OBJ_IS_SOCKET:
+		value = S_IFSOCK;
+		break;
+	case CCS_OBJ_IS_SYMLINK:
+		value = S_IFLNK;
+		break;
+	case CCS_OBJ_IS_FILE:
+		value = S_IFREG;
+		break;
+	case CCS_OBJ_IS_BLOCK_DEV:
+		value = S_IFBLK;
+		break;
+	case CCS_OBJ_IS_DIRECTORY:
+		value = S_IFDIR;
+		break;
+	case CCS_OBJ_IS_CHAR_DEV:
+		value = S_IFCHR;
+		break;
+	case CCS_OBJ_IS_FIFO:
+		value = S_IFIFO;
+		break;
+	case CCS_EXEC_ARGC:
+		if (!bprm)
+			return false;
+		value = bprm->argc;
+		break;
+	case CCS_EXEC_ENVC:
+		if (!bprm)
+			return false;
+		value = bprm->envc;
+		break;
+	case CCS_TASK_TYPE:
+		value = ((u8) ccs_current_flags()) &
+			CCS_TASK_IS_EXECUTE_HANDLER;
+		break;
+	case CCS_TASK_EXECUTE_HANDLER:
+		value = CCS_TASK_IS_EXECUTE_HANDLER;
+		break;
+	case CCS_IMM_NUMBER_ENTRY1:
+		value = (*condp)->value;
+		(*condp)++;
+		break;
+	case CCS_COND_NARG0:
+		value = param->i[0];
+		break;
+	case CCS_COND_NARG1:
+		value = param->i[1];
+		break;
+	case CCS_COND_NARG2:
+		value = param->i[2];
+		break;
+	default:
+		goto not_single_value;
+	}
+	arg->value[0] = value;
+	arg->value[1] = value;
+	return true;
+not_single_value:
+	if (cmd == CCS_IMM_NUMBER_ENTRY2) {
+		arg->value[0] = (*condp)->value;
+		(*condp)++;
+		arg->value[1] = (*condp)->value;
+		(*condp)++;
+		return true;
+	}
+	switch (cmd) {
+	case CCS_COND_SARG0:
+		arg->name = r->param.s[0];
+		break;
+	case CCS_COND_SARG1:
+		arg->name = r->param.s[1];
+		break;
+	case CCS_COND_SARG2:
+		arg->name = r->param.s[2];
+		break;
+	default:
+		goto not_single_name;
+	}
+	if (!arg->name)
+		return false;
+	arg->type = CCS_ARG_TYPE_NAME;
+	return true;
+not_single_name:
+	if (cmd == CCS_COND_DOMAIN) {
+		arg->type = CCS_ARG_TYPE_DOMAINNAME;
+		arg->domainname = (*condp)->path;
+		(*condp)++;
+		return true;
+	}
+	if (cmd == CCS_SELF_DOMAIN) {
+		arg->type = CCS_ARG_TYPE_DOMAINNAME;
+		arg->domainname = ccs_current_domain()->domainname;
+		return true;
+	}
+	if (cmd == CCS_IMM_GROUP) {
+		arg->type = CCS_ARG_TYPE_GROUP;
+		arg->group = (*condp)->group;
+		(*condp)++;
+		return true;
+	}
+	switch (cmd) {
+	case CCS_MODE_SETUID:
+		value = S_ISUID;
+		break;
+	case CCS_MODE_SETGID:
+		value = S_ISGID;
+		break;
+	case CCS_MODE_STICKY:
+		value = S_ISVTX;
+		break;
+	case CCS_MODE_OWNER_READ:
+		value = S_IRUSR;
+		break;
+	case CCS_MODE_OWNER_WRITE:
+		value = S_IWUSR;
+		break;
+	case CCS_MODE_OWNER_EXECUTE:
+		value = S_IXUSR;
+		break;
+	case CCS_MODE_GROUP_READ:
+		value = S_IRGRP;
+		break;
+	case CCS_MODE_GROUP_WRITE:
+		value = S_IWGRP;
+		break;
+	case CCS_MODE_GROUP_EXECUTE:
+		value = S_IXGRP;
+		break;
+	case CCS_MODE_OTHERS_READ:
+		value = S_IROTH;
+		break;
+	case CCS_MODE_OTHERS_WRITE:
+		value = S_IWOTH;
+		break;
+	case CCS_MODE_OTHERS_EXECUTE:
+		value = S_IXOTH;
+		break;
+	default:
+		goto not_bitop;
+	}
+	arg->type = CCS_ARG_TYPE_BITOP;
+	arg->value[0] = value;
+	return true;
+not_bitop:
+	arg->type = CCS_ARG_TYPE_NUMBER;
+	if (!obj)
+		return false;
+	if (!obj->validate_done) {
+		ccs_get_attributes(obj);
+		obj->validate_done = true;
+	}
+	value = (cmd - CCS_PATH_ATTRIBUTE_START) >> 4;
+	if (value > 3)
+		return false;
+	stat = &obj->stat[value];
+	if (!stat)
+		return false;
+	switch ((cmd - CCS_PATH_ATTRIBUTE_START) & 0xF) {
+	case CCS_PATH_ATTRIBUTE_UID:
+		value = stat->uid;
+		break;
+	case CCS_PATH_ATTRIBUTE_GID:
+		value = stat->gid;
+		break;
+	case CCS_PATH_ATTRIBUTE_INO:
+		value = stat->ino;
+		break;
+	case CCS_PATH_ATTRIBUTE_MAJOR:
+		value = MAJOR(stat->dev);
+		break;
+	case CCS_PATH_ATTRIBUTE_MINOR:
+		value = MINOR(stat->dev);
+		break;
+	case CCS_PATH_ATTRIBUTE_TYPE:
+		value = stat->mode & S_IFMT;
+		break;
+	case CCS_PATH_ATTRIBUTE_DEV_MAJOR:
+		value = MAJOR(stat->rdev);
+		break;
+	case CCS_PATH_ATTRIBUTE_DEV_MINOR:
+		value = MINOR(stat->rdev);
+		break;
+	case CCS_PATH_ATTRIBUTE_PERM:
+		value = stat->mode & S_IALLUGO;
+		break;
+	default:
+		return false;
+	}
+	arg->value[0] = value;
+	arg->value[1] = value;
+	return true;
+}
+
 /**
  * ccs_condition - Check condition part.
  *
@@ -3936,368 +3644,134 @@
 bool ccs_condition(struct ccs_request_info *r,
 		   const struct ccs_condition *cond)
 {
-	const u32 ccs_flags = ccs_current_flags();
-	u32 i;
-	unsigned long min_v[2] = { 0, 0 };
-	unsigned long max_v[2] = { 0, 0 };
-	const struct ccs_condition_element *condp;
-	const struct ccs_number_union *numbers_p;
-	const struct ccs_name_union *names_p;
-	const struct ccs_argv *argv;
-	const struct ccs_envp *envp;
+	const union ccs_condition_element *condp;
 	struct ccs_obj_info *obj;
-	u16 condc;
-	u16 argc;
-	u16 envc;
-	struct linux_binprm *bprm = NULL;
+	struct linux_binprm *bprm;
 	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 ccs_condition_element *) (cond + 1);
-	numbers_p = (const struct ccs_number_union *) (condp + condc);
-	names_p = (const struct ccs_name_union *)
-		(numbers_p + cond->numbers_count);
-	argv = (const struct ccs_argv *) (names_p + cond->names_count);
-	envp = (const struct ccs_envp *) (argv + argc);
-	for (i = 0; i < condc; i++) {
+	bprm = r->ee ? r->ee->bprm : NULL;
+	condp = (typeof(condp)) (cond + 1);
+	while ((void *) condp < (void *) ((u8 *) cond) + cond->size) {
+		struct ccs_cond_arg left;
+		struct ccs_cond_arg right;
+		const enum ccs_conditions_index left_op = condp->left;
+		const enum ccs_conditions_index right_op = condp->right;
 		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 == CCS_ARGV_ENTRY || left == CCS_ENVP_ENTRY)
-			continue;
-		/* Check string expressions. */
-		if (right == CCS_NAME_UNION) {
-			const struct ccs_name_union *ptr = names_p++;
-			if (left == CCS_EXEC_REALPATH) {
-				struct ccs_execve *ee = r->ee;
-				struct file *file = ee ? ee->bprm->file : NULL;
-				if (!ccs_scan_exec_realpath(file, ptr, match))
-					goto out;
+		if (!ccs_cond2arg(&left, left_op, &condp, r))
+			return false;
+		if (!ccs_cond2arg(&right, right_op, &condp, r))
+			return false;
+		if (left.type == CCS_ARG_TYPE_NUMBER) {
+			if (right.type == CCS_ARG_TYPE_NUMBER) {
+				if ((left.value[0] <= right.value[1] &&
+				     left.value[1] >= right.value[0]) == match)
+					continue;
+				return false;
 			}
-			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 CCS_TASK_UID:
-				value = current_uid();
-				break;
-			case CCS_TASK_EUID:
-				value = current_euid();
-				break;
-			case CCS_TASK_SUID:
-				value = current_suid();
-				break;
-			case CCS_TASK_FSUID:
-				value = current_fsuid();
-				break;
-			case CCS_TASK_GID:
-				value = current_gid();
-				break;
-			case CCS_TASK_EGID:
-				value = current_egid();
-				break;
-			case CCS_TASK_SGID:
-				value = current_sgid();
-				break;
-			case CCS_TASK_FSGID:
-				value = current_fsgid();
-				break;
-			case CCS_TASK_PID:
-				value = ccs_sys_getpid();
-				break;
-			case CCS_TASK_PPID:
-				value = ccs_sys_getppid();
-				break;
-			case CCS_TYPE_IS_SOCKET:
-				value = S_IFSOCK;
-				break;
-			case CCS_TYPE_IS_SYMLINK:
-				value = S_IFLNK;
-				break;
-			case CCS_TYPE_IS_FILE:
-				value = S_IFREG;
-				break;
-			case CCS_TYPE_IS_BLOCK_DEV:
-				value = S_IFBLK;
-				break;
-			case CCS_TYPE_IS_DIRECTORY:
-				value = S_IFDIR;
-				break;
-			case CCS_TYPE_IS_CHAR_DEV:
-				value = S_IFCHR;
-				break;
-			case CCS_TYPE_IS_FIFO:
-				value = S_IFIFO;
-				break;
-			case CCS_MODE_SETUID:
-				value = S_ISUID;
-				break;
-			case CCS_MODE_SETGID:
-				value = S_ISGID;
-				break;
-			case CCS_MODE_STICKY:
-				value = S_ISVTX;
-				break;
-			case CCS_MODE_OWNER_READ:
-				value = S_IRUSR;
-				break;
-			case CCS_MODE_OWNER_WRITE:
-				value = S_IWUSR;
-				break;
-			case CCS_MODE_OWNER_EXECUTE:
-				value = S_IXUSR;
-				break;
-			case CCS_MODE_GROUP_READ:
-				value = S_IRGRP;
-				break;
-			case CCS_MODE_GROUP_WRITE:
-				value = S_IWGRP;
-				break;
-			case CCS_MODE_GROUP_EXECUTE:
-				value = S_IXGRP;
-				break;
-			case CCS_MODE_OTHERS_READ:
-				value = S_IROTH;
-				break;
-			case CCS_MODE_OTHERS_WRITE:
-				value = S_IWOTH;
-				break;
-			case CCS_MODE_OTHERS_EXECUTE:
-				value = S_IXOTH;
-				break;
-			case CCS_EXEC_ARGC:
-				if (!bprm)
-					goto out;
-				value = bprm->argc;
-				break;
-			case CCS_EXEC_ENVC:
-				if (!bprm)
-					goto out;
-				value = bprm->envc;
-				break;
-			case CCS_TASK_TYPE:
-				value = ((u8) ccs_flags)
-					& CCS_TASK_IS_EXECUTE_HANDLER;
-				break;
-			case CCS_TASK_EXECUTE_HANDLER:
-				value = CCS_TASK_IS_EXECUTE_HANDLER;
-				break;
-			case CCS_NUMBER_UNION:
-				/* Fetch values later. */
-				break;
-			default:
-				if (!obj)
-					goto out;
-				if (!obj->validate_done) {
-					ccs_get_attributes(obj);
-					obj->validate_done = true;
-				}
-				{
-					u8 stat_index;
-					struct ccs_mini_stat *stat;
-					switch (index) {
-					case CCS_PATH1_UID:
-					case CCS_PATH1_GID:
-					case CCS_PATH1_INO:
-					case CCS_PATH1_MAJOR:
-					case CCS_PATH1_MINOR:
-					case CCS_PATH1_TYPE:
-					case CCS_PATH1_DEV_MAJOR:
-					case CCS_PATH1_DEV_MINOR:
-					case CCS_PATH1_PERM:
-						stat_index = CCS_PATH1;
-						break;
-					case CCS_PATH2_UID:
-					case CCS_PATH2_GID:
-					case CCS_PATH2_INO:
-					case CCS_PATH2_MAJOR:
-					case CCS_PATH2_MINOR:
-					case CCS_PATH2_TYPE:
-					case CCS_PATH2_DEV_MAJOR:
-					case CCS_PATH2_DEV_MINOR:
-					case CCS_PATH2_PERM:
-						stat_index = CCS_PATH2;
-						break;
-					case CCS_PATH1_PARENT_UID:
-					case CCS_PATH1_PARENT_GID:
-					case CCS_PATH1_PARENT_INO:
-					case CCS_PATH1_PARENT_PERM:
-						stat_index = CCS_PATH1_PARENT;
-						break;
-					case CCS_PATH2_PARENT_UID:
-					case CCS_PATH2_PARENT_GID:
-					case CCS_PATH2_PARENT_INO:
-					case CCS_PATH2_PARENT_PERM:
-						stat_index = CCS_PATH2_PARENT;
-						break;
-					default:
-						goto out;
-					}
-					if (!obj->stat_valid[stat_index])
-						goto out;
-					stat = &obj->stat[stat_index];
-					switch (index) {
-					case CCS_PATH1_UID:
-					case CCS_PATH2_UID:
-					case CCS_PATH1_PARENT_UID:
-					case CCS_PATH2_PARENT_UID:
-						value = stat->uid;
-						break;
-					case CCS_PATH1_GID:
-					case CCS_PATH2_GID:
-					case CCS_PATH1_PARENT_GID:
-					case CCS_PATH2_PARENT_GID:
-						value = stat->gid;
-						break;
-					case CCS_PATH1_INO:
-					case CCS_PATH2_INO:
-					case CCS_PATH1_PARENT_INO:
-					case CCS_PATH2_PARENT_INO:
-						value = stat->ino;
-						break;
-					case CCS_PATH1_MAJOR:
-					case CCS_PATH2_MAJOR:
-						value = MAJOR(stat->dev);
-						break;
-					case CCS_PATH1_MINOR:
-					case CCS_PATH2_MINOR:
-						value = MINOR(stat->dev);
-						break;
-					case CCS_PATH1_TYPE:
-					case CCS_PATH2_TYPE:
-						value = stat->mode & S_IFMT;
-						break;
-					case CCS_PATH1_DEV_MAJOR:
-					case CCS_PATH2_DEV_MAJOR:
-						value = MAJOR(stat->rdev);
-						break;
-					case CCS_PATH1_DEV_MINOR:
-					case CCS_PATH2_DEV_MINOR:
-						value = MINOR(stat->rdev);
-						break;
-					case CCS_PATH1_PERM:
-					case CCS_PATH2_PERM:
-					case CCS_PATH1_PARENT_PERM:
-					case CCS_PATH2_PARENT_PERM:
-						value = stat->mode & S_IALLUGO;
-						break;
-					}
-				}
-				break;
+			if (right.type == CCS_ARG_TYPE_GROUP) {
+				if (ccs_number_matches_group
+				    (left.value[0], left.value[1], right.group)
+				    == match)
+					continue;
+				return false;
 			}
-			max_v[j] = value;
-			min_v[j] = value;
-			switch (index) {
-			case CCS_MODE_SETUID:
-			case CCS_MODE_SETGID:
-			case CCS_MODE_STICKY:
-			case CCS_MODE_OWNER_READ:
-			case CCS_MODE_OWNER_WRITE:
-			case CCS_MODE_OWNER_EXECUTE:
-			case CCS_MODE_GROUP_READ:
-			case CCS_MODE_GROUP_WRITE:
-			case CCS_MODE_GROUP_EXECUTE:
-			case CCS_MODE_OTHERS_READ:
-			case CCS_MODE_OTHERS_WRITE:
-			case CCS_MODE_OTHERS_EXECUTE:
-				is_bitop[j] = true;
+			if (right.type == CCS_ARG_TYPE_BITOP) {
+				if (!(left.value[0] & right.value[0]) ==
+				    !match)
+					continue;
+				return false;
 			}
+			return false;
 		}
-		if (left == CCS_NUMBER_UNION) {
-			/* Fetch values now. */
-			const struct ccs_number_union *ptr = numbers_p++;
-			min_v[0] = ptr->values[0];
-			max_v[0] = ptr->values[1];
-		}
-		if (right == CCS_NUMBER_UNION) {
-			/* Fetch values now. */
-			const struct ccs_number_union *ptr = numbers_p++;
-			if (ptr->group) {
-				if ((ccs_number_matches_group(min_v[0],
-							      max_v[0],
-							      ptr->group)
-				     != ptr->is_not) == match)
+		if (left.type == CCS_ARG_TYPE_NAME) {
+			if (right.type == CCS_ARG_TYPE_NAME) {
+				if (ccs_path_matches_pattern
+				    (left.name, right.name) == match)
 					continue;
-			} else {
-				if ((min_v[0] <= ptr->values[1] &&
-				     max_v[0] >= ptr->values[0]) == match)
+				return false;
+			}
+			if (right.type == CCS_ARG_TYPE_GROUP) {
+				if (ccs_path_matches_group
+				    (left.name, right.group) == match)
 					continue;
+				return false;
 			}
-			goto out;
+			return false;
 		}
-		/*
-		 * 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 CCS_PATH1_PERM:
-			case CCS_PATH1_PARENT_PERM:
-			case CCS_PATH2_PERM:
-			case CCS_PATH2_PARENT_PERM:
-				if (!(max_v[0] & max_v[1]) == !match)
+		if (left.type == CCS_ARG_TYPE_DOMAINNAME) {
+			BUG_ON(right.type != CCS_ARG_TYPE_DOMAINNAME);
+			if (!ccs_pathcmp(left.domainname,
+					 right.domainname) == match)
+				continue;
+			return false;
+		}
+		/* Check IPv4 or IPv6 address expressions. */
+		if (left.type == CCS_COND_IPARG) {
+			if (right.type == CCS_IMM_GROUP) {
+				if (ccs_address_matches_group
+				    (true, r->param.ip, right.group)
+				    == match)
 					continue;
+				return false;
 			}
-			goto out;
-		} else if (is_bitop[1]) {
-			switch (left) {
-			case CCS_PATH1_PERM:
-			case CCS_PATH1_PARENT_PERM:
-			case CCS_PATH2_PERM:
-			case CCS_PATH2_PARENT_PERM:
-				if (!(max_v[0] & max_v[1]) == !match)
+			if (right.type == CCS_IMM_IPV6ADDR_ENTRY1) {
+				if (!memcmp(&left.ipv6[0], &right.ipv6[0], 16)
+				    == !match)
 					continue;
+				return false;
 			}
-			goto out;
+			if (right.type == CCS_IMM_IPV6ADDR_ENTRY2) {
+				struct in6_addr *ip = &left.ipv6[0];
+				if ((memcmp(ip, &right.ipv6[0], 16) >= 0 &&
+				     memcmp(ip, &right.ipv6[1], 16) <= 0)
+				    == match)
+					continue;
+				return false;
+			}
+			return false;
 		}
-		/* Normal value range comparison. */
-		if ((min_v[0] <= max_v[1] && max_v[0] >= min_v[1]) == match)
+		if (left.type == CCS_HANDLER_PATH) {
+			r->handler_path = condp->path;
+			condp++;
 			continue;
-out:
+		}
+		if (left.type == CCS_TRANSIT_DOMAIN) {
+			r->transition = condp->path;
+			condp++;
+			continue;
+		}
+		if (!bprm)
+			return false;
+		if (left.type == CCS_ARGV_ENTRY) {
+			unsigned long index;
+			const struct ccs_path_info *value;
+			index = condp->value;
+			condp++;
+			value = condp->path;
+			condp++;
+			if (!ccs_check_argv(r->ee, index, value, !match))
+				return false;
+			continue;
+		}
+		if (left.type == CCS_ENVP_ENTRY) {
+			const struct ccs_path_info *name;
+			const struct ccs_path_info *value;
+			name = condp->path;
+			condp++;
+			value = condp->path;
+			condp++;
+			if (!ccs_check_envp(r->ee, name, value, !match))
+				return false;
+			continue;
+		}
 		return false;
 	}
-	/* Check argv[] and envp[] now. */
-	if (r->ee && (argc || envc))
-		return ccs_scan_bprm(r->ee, argc, argv, envc, envp);
 	return true;
 }
 
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-
 /**
- * ccs_check_task_acl - Check permission for task operation.
- *
- * @r:   Pointer to "struct ccs_request_info".
- * @ptr: Pointer to "struct ccs_acl_info".
- *
- * Returns true if granted, false otherwise.
- */
-static bool ccs_check_task_acl(struct ccs_request_info *r,
-			       const struct ccs_acl_info *ptr)
-{
-	const struct ccs_task_acl *acl = container_of(ptr, typeof(*acl), head);
-	return !ccs_pathcmp(r->param.task.domainname, acl->domainname);
-}
-
-#endif
-
-/**
  * ccs_check_auto_domain_transition - Check "task auto_domain_transition" entry.
  *
  * Returns nothing.
@@ -4314,12 +3788,11 @@
 	const int idx = ccs_read_lock();
 	for (i = 0; i < 255; i++) {
 		struct ccs_request_info r = { };
-		r.param_type = CCS_TYPE_AUTO_TASK_ACL;
+		r.type = CCS_MAC_AUTO_TASK_TRANSITION;
 		ccs_check_acl(&r);
 		if (!r.granted)
 			goto done;
-		buf = container_of(r.matched_acl, typeof(struct ccs_task_acl),
-				   head)->domainname->name;
+		buf = r.transition->name;
 		if (!ccs_assign_domain(buf, true))
 			break;
 	}
@@ -4413,20 +3886,12 @@
 			if (c == '/') {
 				return false;
 			} else if (c == '\\') {
-				if (filename[1] == '\\')
-					filename++;
-				else if (ccs_byte_range(filename + 1))
+				if (ccs_byte_range(filename + 1))
 					filename += 3;
 				else
 					return false;
 			}
 			break;
-		case '\\':
-			if (c != '\\')
-				return false;
-			if (*++filename != '\\')
-				return false;
-			break;
 		case '+':
 			if (!ccs_decimal(c))
 				return false;
@@ -4463,9 +3928,7 @@
 					break;
 				if (c != '\\')
 					continue;
-				if (filename[i + 1] == '\\')
-					i++;
-				else if (ccs_byte_range(filename + i + 1))
+				if (ccs_byte_range(filename + i + 1))
 					i += 3;
 				else
 					break; /* Bad pattern. */
Index: gc.c
===================================================================
--- gc.c	(revision 5811)
+++ gc.c	(working copy)
@@ -54,13 +54,10 @@
 static bool ccs_struct_used_by_io_buffer(const struct list_head *element);
 static int ccs_gc_thread(void *unused);
 static void ccs_collect_acl(struct list_head *list);
-static void ccs_collect_domain(struct list_head *list);
 static void ccs_collect_entry(void);
 static void ccs_collect_member(const enum ccs_policy_id id,
 			       struct list_head *member_list);
 static void ccs_memory_free(const void *ptr, const enum ccs_policy_id type);
-static void ccs_put_name_union(struct ccs_name_union *ptr);
-static void ccs_put_number_union(struct ccs_number_union *ptr);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
 static void ccs_synchronize_counter(void);
 #endif
@@ -113,47 +110,19 @@
 		[CCS_ID_MANAGER] = sizeof(struct ccs_manager),
 		/* [CCS_ID_CONDITION] = "struct ccs_condition"->size, */
 		/* [CCS_ID_NAME] = "struct ccs_name"->size, */
-		/* [CCS_ID_ACL] = a["struct ccs_acl_info"->type], */
+		/* [CCS_ID_ACL] = sizeof(struct ccs_acl_info), */
 		[CCS_ID_DOMAIN] = sizeof(struct ccs_domain_info),
 	};
-	/* Size of a domain ACL element. */
-	static const u8 a[] = {
-		[CCS_TYPE_PATH_ACL] = sizeof(struct ccs_path_acl),
-		[CCS_TYPE_PATH2_ACL] = sizeof(struct ccs_path2_acl),
-		[CCS_TYPE_PATH_NUMBER_ACL]
-		= sizeof(struct ccs_path_number_acl),
-		[CCS_TYPE_MKDEV_ACL] = sizeof(struct ccs_mkdev_acl),
-		[CCS_TYPE_MOUNT_ACL] = sizeof(struct ccs_mount_acl),
-#ifdef CONFIG_CCSECURITY_NETWORK
-		[CCS_TYPE_INET_ACL] = sizeof(struct ccs_inet_acl),
-		[CCS_TYPE_UNIX_ACL] = sizeof(struct ccs_unix_acl),
-#endif
-#ifdef CONFIG_CCSECURITY_MISC
-		[CCS_TYPE_ENV_ACL] = sizeof(struct ccs_env_acl),
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-		[CCS_TYPE_CAPABILITY_ACL] = sizeof(struct ccs_capability_acl),
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-		[CCS_TYPE_PTRACE_ACL] = sizeof(struct ccs_ptrace_acl),
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-		[CCS_TYPE_AUTO_EXECUTE_HANDLER]
-		= sizeof(struct ccs_handler_acl),
-		[CCS_TYPE_DENIED_EXECUTE_HANDLER]
-		= sizeof(struct ccs_handler_acl),
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-		[CCS_TYPE_AUTO_TASK_ACL] = sizeof(struct ccs_task_acl),
-		[CCS_TYPE_MANUAL_TASK_ACL] = sizeof(struct ccs_task_acl),
-#endif
-		[CCS_TYPE_USE_GROUP_ACL] = sizeof(struct ccs_use_group_acl),
-	};
 	size_t size;
-	if (type == CCS_ID_ACL)
-		size = a[container_of(ptr, typeof(struct ccs_acl_info),
-				      list)->type];
-	else if (type == CCS_ID_NAME)
+	if (type == CCS_ID_ACL) {
+		const enum ccs_mac_index subtype =
+			container_of(ptr, typeof(struct ccs_acl_info),
+				     list)->type;
+		if (subtype == CCS_MAC_USE_GROUP)
+			size = sizeof(struct ccs_use_group_acl);
+		else
+			size = sizeof(struct ccs_acl_info);
+	} else if (type == CCS_ID_NAME)
 		size = container_of(ptr, typeof(struct ccs_name),
 				    head.list)->size;
 	else if (type == CCS_ID_CONDITION)
@@ -166,31 +135,6 @@
 }
 
 /**
- * ccs_put_name_union - Drop reference on "struct ccs_name_union".
- *
- * @ptr: Pointer to "struct ccs_name_union".
- *
- * Returns nothing.
- */
-static void ccs_put_name_union(struct ccs_name_union *ptr)
-{
-	ccs_put_group(ptr->group);
-	ccs_put_name(ptr->filename);
-}
-
-/**
- * ccs_put_number_union - Drop reference on "struct ccs_number_union".
- *
- * @ptr: Pointer to "struct ccs_number_union".
- *
- * Returns nothing.
- */
-static void ccs_put_number_union(struct ccs_number_union *ptr)
-{
-	ccs_put_group(ptr->group);
-}
-
-/**
  * ccs_struct_used_by_io_buffer - Check whether the list element is used by /proc/ccs/ users or not.
  *
  * @element: Pointer to "struct list_head".
@@ -347,119 +291,10 @@
 {
 	struct ccs_acl_info *acl = container_of(element, typeof(*acl), list);
 	ccs_put_condition(acl->cond);
-	switch (acl->type) {
-	case CCS_TYPE_PATH_ACL:
-		{
-			struct ccs_path_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->name);
-		}
-		break;
-	case CCS_TYPE_PATH2_ACL:
-		{
-			struct ccs_path2_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->name1);
-			ccs_put_name_union(&entry->name2);
-		}
-		break;
-	case CCS_TYPE_PATH_NUMBER_ACL:
-		{
-			struct ccs_path_number_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->name);
-			ccs_put_number_union(&entry->number);
-		}
-		break;
-	case CCS_TYPE_MKDEV_ACL:
-		{
-			struct ccs_mkdev_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->name);
-			ccs_put_number_union(&entry->mode);
-			ccs_put_number_union(&entry->major);
-			ccs_put_number_union(&entry->minor);
-		}
-		break;
-	case CCS_TYPE_MOUNT_ACL:
-		{
-			struct ccs_mount_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->dev_name);
-			ccs_put_name_union(&entry->dir_name);
-			ccs_put_name_union(&entry->fs_type);
-			ccs_put_number_union(&entry->flags);
-		}
-		break;
-#ifdef CONFIG_CCSECURITY_NETWORK
-	case CCS_TYPE_INET_ACL:
-		{
-			struct ccs_inet_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_group(entry->address.group);
-			ccs_put_number_union(&entry->port);
-		}
-		break;
-	case CCS_TYPE_UNIX_ACL:
-		{
-			struct ccs_unix_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->name);
-		}
-		break;
-#endif
-#ifdef CONFIG_CCSECURITY_MISC
-	case CCS_TYPE_ENV_ACL:
-		{
-			struct ccs_env_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name_union(&entry->env);
-		}
-		break;
-#endif
-#ifdef CONFIG_CCSECURITY_CAPABILITY
-	case CCS_TYPE_CAPABILITY_ACL:
-		{
-			/* Nothing to do. */
-		}
-		break;
-#endif
-#ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_PTRACE_ACL:
-		{
-			struct ccs_ptrace_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_number_union(&entry->request);
-			ccs_put_name(entry->domainname);
-		}
-		break;
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-	case CCS_TYPE_AUTO_EXECUTE_HANDLER:
-	case CCS_TYPE_DENIED_EXECUTE_HANDLER:
-		{
-			struct ccs_handler_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name(entry->handler);
-		}
-		break;
-#endif
-#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
-	case CCS_TYPE_AUTO_TASK_ACL:
-	case CCS_TYPE_MANUAL_TASK_ACL:
-		{
-			struct ccs_task_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_name(entry->domainname);
-		}
-		break;
-#endif
-	case CCS_TYPE_USE_GROUP_ACL:
-		{
-			struct ccs_use_group_acl *entry =
-				container_of(acl, typeof(*entry), head);
-			ccs_put_group(entry->group);
-		}
+	if (acl->type == CCS_MAC_USE_GROUP) {
+		struct ccs_use_group_acl *entry =
+			container_of(acl, typeof(*entry), head);
+		ccs_put_group(entry->group);
 	}
 }
 
@@ -489,7 +324,6 @@
 	}
 	ccs_put_name(domain->default_transition);
 	ccs_put_name(domain->domainname);
-	ccs_put_condition(domain->cond);
 }
 
 /**
@@ -555,31 +389,39 @@
 {
 	struct ccs_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 ccs_condition_element *condp
-		= (const struct ccs_condition_element *) (cond + 1);
-	struct ccs_number_union *numbers_p
-		= (struct ccs_number_union *) (condp + condc);
-	struct ccs_name_union *names_p
-		= (struct ccs_name_union *) (numbers_p + numbers_count);
-	const struct ccs_argv *argv
-		= (const struct ccs_argv *) (names_p + names_count);
-	const struct ccs_envp *envp
-		= (const struct ccs_envp *) (argv + argc);
-	for (i = 0; i < numbers_count; i++)
-		ccs_put_number_union(numbers_p++);
-	for (i = 0; i < names_count; i++)
-		ccs_put_name_union(names_p++);
-	for (i = 0; i < argc; argv++, i++)
-		ccs_put_name(argv->value);
-	for (i = 0; i < envc; envp++, i++) {
-		ccs_put_name(envp->name);
-		ccs_put_name(envp->value);
+	const union ccs_condition_element *condp = (typeof(condp)) (cond + 1);
+	while ((void *) condp < (void *) ((u8 *) cond) + cond->size) {
+		const enum ccs_conditions_index left = condp->left;
+		const enum ccs_conditions_index right = condp->right;
+		condp++;
+		if (left == CCS_ARGV_ENTRY)
+			condp++;
+		else if (left == CCS_ENVP_ENTRY) {
+			ccs_put_name(condp->path);
+			condp++;
+		} else if (left == CCS_HANDLER_PATH ||
+			   left == CCS_TRANSIT_DOMAIN) {
+			ccs_put_name(condp->path);
+			condp++;
+			continue;
+		}
+		if (right == CCS_IMM_GROUP) {
+			ccs_put_group(condp->group);
+			condp++;
+		} else if (right == CCS_IMM_NAME_ENTRY ||
+			   right == CCS_IMM_DOMAINNAME_ENTRY) {
+			ccs_put_name(condp->path);
+			condp++;
+		} else if (right == CCS_IMM_NUMBER_ENTRY1)
+			condp++;
+		else if (right == CCS_IMM_NUMBER_ENTRY2)
+			condp += 2;
+		else if (right == CCS_IMM_IPV6ADDR_ENTRY1)
+			condp = (void *)
+				(((u8 *) condp) + sizeof(struct in6_addr));
+		else if (right == CCS_IMM_IPV6ADDR_ENTRY2)
+			condp = (void *)
+				(((u8 *) condp) + sizeof(struct in6_addr) * 2);
 	}
 }
 
@@ -806,27 +648,6 @@
 }
 
 /**
- * ccs_collect_domain - Delete domains in "struct ccs_acl_info".
- *
- * @list: Pointer to "struct list_head".
- *
- * Returns nothing.
- *
- * Caller holds ccs_policy_lock mutex.
- */
-static void ccs_collect_domain(struct list_head *list)
-{
-	struct ccs_domain_info *domain;
-	struct ccs_domain_info *tmp;
-	list_for_each_entry_safe(domain, tmp, list, list) {
-		if (!domain->is_deleted)
-			continue;
-		domain->is_deleted = CCS_GC_IN_PROGRESS;
-		ccs_try_to_gc(CCS_ID_DOMAIN, &domain->list);
-	}
-}
-
-/**
  * ccs_collect_entry - Try to kfree() deleted elements.
  *
  * Returns nothing.
@@ -834,7 +655,6 @@
 static void ccs_collect_entry(void)
 {
 	int i;
-	struct ccs_policy_namespace *ns;
 	mutex_lock(&ccs_policy_lock);
 	{
 		struct ccs_domain_info *domain;
@@ -848,16 +668,15 @@
 		}
 	}
 	ccs_collect_member(CCS_ID_MANAGER, &ccs_manager_list);
-	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
-		ccs_collect_acl(&ns->default_transition_list);
-	}
+	ccs_collect_acl(&ccs_default_transition_list);
 	{
 		struct ccs_acl_info *ptr;
 		struct ccs_acl_info *tmp;
 		list_for_each_entry_safe(ptr, tmp, &ccs_inversed_acl_list,
-					  list) {
-			ccs_collect_domain(&ptr->domain_list);
-			if (!ptr->is_deleted || !list_empty(&ptr->domain_list))
+					 list) {
+			ccs_collect_acl(&ptr->acl_info_list);
+			if (!ptr->is_deleted ||
+			    !list_empty(&ptr->acl_info_list))
 				continue;
 			ptr->is_deleted = CCS_GC_IN_PROGRESS;
 			ccs_try_to_gc(CCS_ID_ACL, &ptr->list);
@@ -867,53 +686,60 @@
 		struct ccs_shared_acl_head *ptr;
 		struct ccs_shared_acl_head *tmp;
 		list_for_each_entry_safe(ptr, tmp, &ccs_condition_list, list) {
-			if (atomic_read(&ptr->users) > 0)
+			if (atomic_read(&ptr->users)) {
+				/*
+				printk(KERN_INFO "Users=%u condition=%p\n",
+				     atomic_read(&ptr->users), ptr);
+				*/
 				continue;
+			}
 			atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
 			ccs_try_to_gc(CCS_ID_CONDITION, &ptr->list);
 		}
 	}
-	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
-		for (i = 0; i < CCS_MAX_GROUP; i++) {
-			struct list_head *list = &ns->group_list[i];
-			struct ccs_group *group;
-			struct ccs_group *tmp;
-			enum ccs_policy_id id;
-			if (i == CCS_PATH_GROUP)
-				id = CCS_ID_PATH_GROUP;
-			else if (i == CCS_NUMBER_GROUP)
-				id = CCS_ID_NUMBER_GROUP;
-			else if (i == CCS_ACL_GROUP)
-				id = CCS_ID_ACL;
+	for (i = 0; i < CCS_MAX_GROUP; i++) {
+		struct list_head *list = &ccs_group_list[i];
+		struct ccs_group *group;
+		struct ccs_group *tmp;
+		enum ccs_policy_id id;
+		if (i == CCS_PATH_GROUP)
+			id = CCS_ID_PATH_GROUP;
+		else if (i == CCS_NUMBER_GROUP)
+			id = CCS_ID_NUMBER_GROUP;
+		else if (i == CCS_ACL_GROUP)
+			id = CCS_ID_ACL;
 #ifdef CONFIG_CCSECURITY_NETWORK
-			else
-				id = CCS_ID_ADDRESS_GROUP;
+		else
+			id = CCS_ID_ADDRESS_GROUP;
 #endif
-			list_for_each_entry_safe(group, tmp, list, head.list) {
-				if (id == CCS_ID_ACL)
-					ccs_collect_acl(&group->member_list);
-				else
-					ccs_collect_member(id, &group->
-							   member_list);
-				if (!list_empty(&group->member_list) ||
-				    atomic_read(&group->head.users) > 0) {
-					/*
-					if (id == CCS_ID_ACL)
-						printk("%s users=%d\n",
-			       __func__, atomic_read(&group->head.users));
-					*/
-					continue;
-				}
-				atomic_set(&group->head.users,
-					   CCS_GC_IN_PROGRESS);
+		list_for_each_entry_safe(group, tmp, list, head.list) {
+			if (id == CCS_ID_ACL)
+				ccs_collect_acl(&group->member_list);
+			else
+				ccs_collect_member(id, &group->
+						   member_list);
+			if (!list_empty(&group->member_list) ||
+			    atomic_read(&group->head.users)) {
 				/*
-				if (id == CCS_ID_ACL)
-					printk("%s trying to gc %s\n",
-					       __func__,
-					       group->group_name->name);
+				  printk(KERN_INFO "Users=%u group=%p\n",
+				  atomic_read(&group->head.users),
+				  group);
 				*/
-				ccs_try_to_gc(CCS_ID_GROUP, &group->head.list);
+				/*
+				  if (id == CCS_ID_ACL)
+				  printk("%s users=%d\n",
+				  __func__, atomic_read(&group->head.users));
+				*/
+				continue;
 			}
+			atomic_set(&group->head.users, CCS_GC_IN_PROGRESS);
+			/*
+			if (id == CCS_ID_ACL)
+				printk("%s trying to gc %s\n",
+				       __func__,
+				       group->group_name->name);
+			*/
+			ccs_try_to_gc(CCS_ID_GROUP, &group->head.list);
 		}
 	}
 	for (i = 0; i < CCS_MAX_HASH; i++) {
@@ -921,8 +747,15 @@
 		struct ccs_shared_acl_head *ptr;
 		struct ccs_shared_acl_head *tmp;
 		list_for_each_entry_safe(ptr, tmp, list, list) {
-			if (atomic_read(&ptr->users) > 0)
+			if (atomic_read(&ptr->users)) {
+				/*
+				  printk(KERN_INFO "Users=%u Name='%s'\n",
+				       atomic_read(&ptr->users),
+				       container_of(ptr, struct ccs_name,
+						    head)->entry.name);
+				*/
 				continue;
+			}
 			atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
 			ccs_try_to_gc(CCS_ID_NAME, &ptr->list);
 		}
