TOMOYO: Add environment variable name restriction support.

This patch adds support for checking environment variable's names.
Although TOMOYO already provides ability to check argv[]/envp[] passed to
execve() requests,

  file execute /bin/sh exec.envp["LD_LIBRARY_PATH"]="bar"

will reject execution of /bin/sh if environment variable LD_LIBRARY_PATH is not
defined. To grant execution of /bin/sh if LD_LIBRARY_PATH is not defined,
administrators have to specify like

  file execute /bin/sh exec.envp["LD_LIBRARY_PATH"]="/system/lib"
  file execute /bin/sh exec.envp["LD_LIBRARY_PATH"]=NULL

. Since there are many environment variables whereas conditional checks are
applied as "&&", it is difficult to cover all combinations. Therefore, this
patch supports conditional checks that are applied as "||", by specifying like

  file execute /bin/sh
  misc env LD_LIBRARY_PATH exec.envp["LD_LIBRARY_PATH"]="/system/lib"

which means "grant execution of /bin/sh if environment variable is not defined
or is defined and its value is /system/lib".

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index c8439cf2..d116e1e 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -20,6 +20,7 @@
 /* String table for /sys/kernel/security/tomoyo/profile */
 const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
 				       + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
+	/* CONFIG::file group */
 	[TOMOYO_MAC_FILE_EXECUTE]    = "execute",
 	[TOMOYO_MAC_FILE_OPEN]       = "open",
 	[TOMOYO_MAC_FILE_CREATE]     = "create",
@@ -43,7 +44,11 @@
 	[TOMOYO_MAC_FILE_MOUNT]      = "mount",
 	[TOMOYO_MAC_FILE_UMOUNT]     = "unmount",
 	[TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
+	/* CONFIG::misc group */
+	[TOMOYO_MAC_ENVIRON] = "env",
+	/* CONFIG group */
 	[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
+	[TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc",
 };
 
 /* String table for conditions. */
@@ -133,7 +138,8 @@
 /* String table for categories. */
 static const char * const tomoyo_category_keywords
 [TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
-	[TOMOYO_MAC_CATEGORY_FILE]       = "file",
+	[TOMOYO_MAC_CATEGORY_FILE] = "file",
+	[TOMOYO_MAC_CATEGORY_MISC] = "misc",
 };
 
 /* Permit policy management by non-root user? */
@@ -1036,11 +1042,13 @@
 	static const struct {
 		const char *keyword;
 		int (*write) (struct tomoyo_acl_param *);
-	} tomoyo_callback[1] = {
+	} tomoyo_callback[2] = {
 		{ "file ", tomoyo_write_file },
+		{ "misc ", tomoyo_write_misc },
 	};
 	u8 i;
-	for (i = 0; i < 1; i++) {
+
+	for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) {
 		if (!tomoyo_str_starts(&param.data,
 				       tomoyo_callback[i].keyword))
 			continue;
@@ -1375,6 +1383,12 @@
 		tomoyo_print_name_union(head, &ptr->dir_name);
 		tomoyo_print_name_union(head, &ptr->fs_type);
 		tomoyo_print_number_union(head, &ptr->flags);
+	} else if (acl_type == TOMOYO_TYPE_ENV_ACL) {
+		struct tomoyo_env_acl *ptr =
+			container_of(acl, typeof(*ptr), head);
+
+		tomoyo_set_group(head, "misc env ");
+		tomoyo_set_string(head, ptr->env->name);
 	}
 	if (acl->cond) {
 		head->r.print_cond_part = true;