TOMOYO: Add mount restriction.

mount(2) has three string and one numeric parameters.
Split mount restriction code from security/tomoyo/file.c .

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 0706b17..0c6f9a5 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1075,6 +1075,10 @@
 				if (perm & (1 << i))
 					count++;
 			break;
+		case TOMOYO_TYPE_MOUNT_ACL:
+			if (!container_of(ptr, struct tomoyo_mount_acl, head)->
+			    is_deleted)
+				count++;
 		}
 	}
 	if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
@@ -1576,6 +1580,8 @@
 		domain->ignore_global_allow_read = !is_delete;
 		return 0;
 	}
+        if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_MOUNT))
+                return tomoyo_write_mount_policy(data, domain, is_delete);
 	return tomoyo_write_file_policy(data, domain, is_delete);
 }
 
@@ -1721,6 +1727,30 @@
 }
 
 /**
+ * tomoyo_print_mount_acl - Print a mount ACL entry.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ * @ptr:  Pointer to "struct tomoyo_mount_acl".
+ *
+ * Returns true on success, false otherwise.
+ */
+static bool tomoyo_print_mount_acl(struct tomoyo_io_buffer *head,
+				   struct tomoyo_mount_acl *ptr)
+{
+	const int pos = head->read_avail;
+	if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) ||
+	    !tomoyo_print_name_union(head, &ptr->dev_name) ||
+	    !tomoyo_print_name_union(head, &ptr->dir_name) ||
+	    !tomoyo_print_name_union(head, &ptr->fs_type) ||
+	    !tomoyo_print_number_union(head, &ptr->flags) ||
+	    !tomoyo_io_printf(head, "\n")) {
+		head->read_avail = pos;
+		return false;
+	}
+	return true;
+}
+
+/**
  * tomoyo_print_entry - Print an ACL entry.
  *
  * @head: Pointer to "struct tomoyo_io_buffer".
@@ -1755,6 +1785,11 @@
 				       head);
 		return tomoyo_print_path_number3_acl(head, acl);
 	}
+	if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
+		struct tomoyo_mount_acl *acl
+			= container_of(ptr, struct tomoyo_mount_acl, head);
+		return tomoyo_print_mount_acl(head, acl);
+	}
 	BUG(); /* This must not happen. */
 	return false;
 }