summary refs log tree commit diff
path: root/security/tomoyo/common.h
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-24 14:57:16 +0900
committerJames Morris <jmorris@namei.org>2010-08-02 15:34:45 +1000
commitf23571e866309a2048030ef6a5f0725cf139d4c9 (patch)
tree0116bcef462f367307b2db927b249b7ce21039c2 /security/tomoyo/common.h
parent5db5a39b6462c8360c9178b28f4b07c320dfca1c (diff)
downloadlinux-f23571e866309a2048030ef6a5f0725cf139d4c9.tar.gz
TOMOYO: Copy directly to userspace buffer.
When userspace program reads policy from /sys/kernel/security/tomoyo/
interface, TOMOYO uses line buffered mode. A line has at least one word.

Commit 006dacc "TOMOYO: Support longer pathname." changed a word's max length
from 4000 bytes to max kmalloc()able bytes. By that commit, a line's max length
changed from 8192 bytes to more than max kmalloc()able bytes.

Max number of words in a line remains finite. This patch changes the way of
buffering so that all words in a line are firstly directly copied to userspace
buffer as much as possible and are secondly queued for next read request.
Words queued are guaranteed to be valid until /sys/kernel/security/tomoyo/
interface is close()d.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.h')
-rw-r--r--security/tomoyo/common.h63
1 files changed, 22 insertions, 41 deletions
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 67b9aeae80a7..ef8fecddb65a 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -524,28 +524,11 @@ struct tomoyo_mount_acl {
 	struct tomoyo_number_union flags;
 };
 
+#define TOMOYO_MAX_IO_READ_QUEUE 32
+
 /*
- * tomoyo_io_buffer is a structure which is used for reading and modifying
- * configuration via /sys/kernel/security/tomoyo/ interface.
- * It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as
- * cursors.
- *
- * Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of
- * "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info"
- * entry has a list of "struct tomoyo_acl_info", we need two cursors when
- * reading (one is for traversing tomoyo_domain_list and the other is for
- * traversing "struct tomoyo_acl_info"->acl_info_list ).
- *
- * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
- * "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the
- * domain with the domainname specified by the rest of that line (NULL is set
- * if seek failed).
- * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
- * "delete ", TOMOYO deletes an entry or a domain specified by the rest of that
- * line (->write_var1 is set to NULL if a domain was deleted).
- * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
- * neither "select " nor "delete ", an entry or a domain specified by that line
- * is appended.
+ * Structure for reading/writing policy via /sys/kernel/security/tomoyo
+ * interfaces.
  */
 struct tomoyo_io_buffer {
 	void (*read) (struct tomoyo_io_buffer *);
@@ -555,26 +538,27 @@ struct tomoyo_io_buffer {
 	struct mutex io_sem;
 	/* Index returned by tomoyo_read_lock(). */
 	int reader_idx;
-	/* The position currently reading from. */
-	struct list_head *read_var1;
-	/* Extra variables for reading.         */
-	struct list_head *read_var2;
+	char __user *read_user_buf;
+	int read_user_buf_avail;
+	struct {
+		struct list_head *domain;
+		struct list_head *group;
+		struct list_head *acl;
+		int avail;
+		int step;
+		int query_index;
+		u16 index;
+		u8 bit;
+		u8 w_pos;
+		bool eof;
+		bool print_this_domain_only;
+		bool print_execute_only;
+		const char *w[TOMOYO_MAX_IO_READ_QUEUE];
+	} r;
 	/* The position currently writing to.   */
 	struct tomoyo_domain_info *write_var1;
-	/* The step for reading.                */
-	int read_step;
 	/* Buffer for reading.                  */
 	char *read_buf;
-	/* EOF flag for reading.                */
-	bool read_eof;
-	/* Read domain ACL of specified PID?    */
-	bool read_single_domain;
-	/* Extra variable for reading.          */
-	u8 read_bit;
-	/* Read only TOMOYO_TYPE_EXECUTE        */
-	bool print_execute_only;
-	/* Bytes available for reading.         */
-	int read_avail;
 	/* Size of read buffer.                 */
 	int readbuf_size;
 	/* Buffer for writing.                  */
@@ -738,8 +722,7 @@ bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
 bool tomoyo_compare_number_union(const unsigned long value,
 				 const struct tomoyo_number_union *ptr);
 int tomoyo_get_mode(const u8 profile, const u8 index);
-/* Transactional sprintf() for policy dump. */
-bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
+void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
 	__attribute__ ((format(printf, 2, 3)));
 /* Check whether the domainname is correct. */
 bool tomoyo_correct_domain(const unsigned char *domainname);
@@ -761,8 +744,6 @@ bool tomoyo_number_matches_group(const unsigned long min,
 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
 				 const struct tomoyo_path_info *pattern);
 
-bool tomoyo_print_number_union(struct tomoyo_io_buffer *head,
-			       const struct tomoyo_number_union *ptr);
 bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num);
 /* Tokenize a line. */
 bool tomoyo_tokenize(char *buffer, char *w[], size_t size);