diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-24 01:57:16 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:45 -0400 |
commit | f23571e866309a2048030ef6a5f0725cf139d4c9 (patch) | |
tree | 0116bcef462f367307b2db927b249b7ce21039c2 /security/tomoyo/common.h | |
parent | 5db5a39b6462c8360c9178b28f4b07c320dfca1c (diff) |
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.h | 63 |
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 { | |||
524 | struct tomoyo_number_union flags; | 524 | struct tomoyo_number_union flags; |
525 | }; | 525 | }; |
526 | 526 | ||
527 | #define TOMOYO_MAX_IO_READ_QUEUE 32 | ||
528 | |||
527 | /* | 529 | /* |
528 | * tomoyo_io_buffer is a structure which is used for reading and modifying | 530 | * Structure for reading/writing policy via /sys/kernel/security/tomoyo |
529 | * configuration via /sys/kernel/security/tomoyo/ interface. | 531 | * interfaces. |
530 | * It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as | ||
531 | * cursors. | ||
532 | * | ||
533 | * Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of | ||
534 | * "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info" | ||
535 | * entry has a list of "struct tomoyo_acl_info", we need two cursors when | ||
536 | * reading (one is for traversing tomoyo_domain_list and the other is for | ||
537 | * traversing "struct tomoyo_acl_info"->acl_info_list ). | ||
538 | * | ||
539 | * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with | ||
540 | * "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the | ||
541 | * domain with the domainname specified by the rest of that line (NULL is set | ||
542 | * if seek failed). | ||
543 | * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with | ||
544 | * "delete ", TOMOYO deletes an entry or a domain specified by the rest of that | ||
545 | * line (->write_var1 is set to NULL if a domain was deleted). | ||
546 | * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with | ||
547 | * neither "select " nor "delete ", an entry or a domain specified by that line | ||
548 | * is appended. | ||
549 | */ | 532 | */ |
550 | struct tomoyo_io_buffer { | 533 | struct tomoyo_io_buffer { |
551 | void (*read) (struct tomoyo_io_buffer *); | 534 | void (*read) (struct tomoyo_io_buffer *); |
@@ -555,26 +538,27 @@ struct tomoyo_io_buffer { | |||
555 | struct mutex io_sem; | 538 | struct mutex io_sem; |
556 | /* Index returned by tomoyo_read_lock(). */ | 539 | /* Index returned by tomoyo_read_lock(). */ |
557 | int reader_idx; | 540 | int reader_idx; |
558 | /* The position currently reading from. */ | 541 | char __user *read_user_buf; |
559 | struct list_head *read_var1; | 542 | int read_user_buf_avail; |
560 | /* Extra variables for reading. */ | 543 | struct { |
561 | struct list_head *read_var2; | 544 | struct list_head *domain; |
545 | struct list_head *group; | ||
546 | struct list_head *acl; | ||
547 | int avail; | ||
548 | int step; | ||
549 | int query_index; | ||
550 | u16 index; | ||
551 | u8 bit; | ||
552 | u8 w_pos; | ||
553 | bool eof; | ||
554 | bool print_this_domain_only; | ||
555 | bool print_execute_only; | ||
556 | const char *w[TOMOYO_MAX_IO_READ_QUEUE]; | ||
557 | } r; | ||
562 | /* The position currently writing to. */ | 558 | /* The position currently writing to. */ |
563 | struct tomoyo_domain_info *write_var1; | 559 | struct tomoyo_domain_info *write_var1; |
564 | /* The step for reading. */ | ||
565 | int read_step; | ||
566 | /* Buffer for reading. */ | 560 | /* Buffer for reading. */ |
567 | char *read_buf; | 561 | char *read_buf; |
568 | /* EOF flag for reading. */ | ||
569 | bool read_eof; | ||
570 | /* Read domain ACL of specified PID? */ | ||
571 | bool read_single_domain; | ||
572 | /* Extra variable for reading. */ | ||
573 | u8 read_bit; | ||
574 | /* Read only TOMOYO_TYPE_EXECUTE */ | ||
575 | bool print_execute_only; | ||
576 | /* Bytes available for reading. */ | ||
577 | int read_avail; | ||
578 | /* Size of read buffer. */ | 562 | /* Size of read buffer. */ |
579 | int readbuf_size; | 563 | int readbuf_size; |
580 | /* Buffer for writing. */ | 564 | /* Buffer for writing. */ |
@@ -738,8 +722,7 @@ bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, | |||
738 | bool tomoyo_compare_number_union(const unsigned long value, | 722 | bool tomoyo_compare_number_union(const unsigned long value, |
739 | const struct tomoyo_number_union *ptr); | 723 | const struct tomoyo_number_union *ptr); |
740 | int tomoyo_get_mode(const u8 profile, const u8 index); | 724 | int tomoyo_get_mode(const u8 profile, const u8 index); |
741 | /* Transactional sprintf() for policy dump. */ | 725 | void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) |
742 | bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) | ||
743 | __attribute__ ((format(printf, 2, 3))); | 726 | __attribute__ ((format(printf, 2, 3))); |
744 | /* Check whether the domainname is correct. */ | 727 | /* Check whether the domainname is correct. */ |
745 | bool tomoyo_correct_domain(const unsigned char *domainname); | 728 | bool tomoyo_correct_domain(const unsigned char *domainname); |
@@ -761,8 +744,6 @@ bool tomoyo_number_matches_group(const unsigned long min, | |||
761 | bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, | 744 | bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, |
762 | const struct tomoyo_path_info *pattern); | 745 | const struct tomoyo_path_info *pattern); |
763 | 746 | ||
764 | bool tomoyo_print_number_union(struct tomoyo_io_buffer *head, | ||
765 | const struct tomoyo_number_union *ptr); | ||
766 | bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); | 747 | bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); |
767 | /* Tokenize a line. */ | 748 | /* Tokenize a line. */ |
768 | bool tomoyo_tokenize(char *buffer, char *w[], size_t size); | 749 | bool tomoyo_tokenize(char *buffer, char *w[], size_t size); |