aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-24 01:57:16 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:34:45 -0400
commitf23571e866309a2048030ef6a5f0725cf139d4c9 (patch)
tree0116bcef462f367307b2db927b249b7ce21039c2 /security
parent5db5a39b6462c8360c9178b28f4b07c320dfca1c (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')
-rw-r--r--security/tomoyo/common.c891
-rw-r--r--security/tomoyo/common.h63
-rw-r--r--security/tomoyo/memory.c4
3 files changed, 499 insertions, 459 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index a3c3b5de3b75..7cb6c0459d96 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -28,7 +28,7 @@ static unsigned int tomoyo_profile_version;
28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES]; 28static struct tomoyo_profile *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
29 29
30/* String table for functionality that takes 4 modes. */ 30/* String table for functionality that takes 4 modes. */
31static const char *tomoyo_mode_4[4] = { 31static const char *tomoyo_mode[4] = {
32 "disabled", "learning", "permissive", "enforcing" 32 "disabled", "learning", "permissive", "enforcing"
33}; 33};
34 34
@@ -76,102 +76,175 @@ static const char *tomoyo_yesno(const unsigned int value)
76 return value ? "yes" : "no"; 76 return value ? "yes" : "no";
77} 77}
78 78
79static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
80{
81 va_list args;
82 const int pos = strlen(buffer);
83 va_start(args, fmt);
84 vsnprintf(buffer + pos, len - pos - 1, fmt, args);
85 va_end(args);
86}
87
79/** 88/**
80 * tomoyo_print_name_union - Print a tomoyo_name_union. 89 * tomoyo_flush - Flush queued string to userspace's buffer.
81 * 90 *
82 * @head: Pointer to "struct tomoyo_io_buffer". 91 * @head: Pointer to "struct tomoyo_io_buffer".
83 * @ptr: Pointer to "struct tomoyo_name_union".
84 * 92 *
85 * Returns true on success, false otherwise. 93 * Returns true if all data was flushed, false otherwise.
86 */ 94 */
87static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head, 95static bool tomoyo_flush(struct tomoyo_io_buffer *head)
88 const struct tomoyo_name_union *ptr)
89{ 96{
90 int pos = head->read_avail; 97 while (head->r.w_pos) {
91 if (pos && head->read_buf[pos - 1] == ' ') 98 const char *w = head->r.w[0];
92 head->read_avail--; 99 int len = strlen(w);
93 if (ptr->is_group) 100 if (len) {
94 return tomoyo_io_printf(head, " @%s", 101 if (len > head->read_user_buf_avail)
95 ptr->group->group_name->name); 102 len = head->read_user_buf_avail;
96 return tomoyo_io_printf(head, " %s", ptr->filename->name); 103 if (!len)
104 return false;
105 if (copy_to_user(head->read_user_buf, w, len))
106 return false;
107 head->read_user_buf_avail -= len;
108 head->read_user_buf += len;
109 w += len;
110 }
111 if (*w) {
112 head->r.w[0] = w;
113 return false;
114 }
115 /* Add '\0' for query. */
116 if (head->poll) {
117 if (!head->read_user_buf_avail ||
118 copy_to_user(head->read_user_buf, "", 1))
119 return false;
120 head->read_user_buf_avail--;
121 head->read_user_buf++;
122 }
123 head->r.w_pos--;
124 for (len = 0; len < head->r.w_pos; len++)
125 head->r.w[len] = head->r.w[len + 1];
126 }
127 head->r.avail = 0;
128 return true;
97} 129}
98 130
99/** 131/**
100 * tomoyo_print_number_union - Print a tomoyo_number_union. 132 * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure.
101 * 133 *
102 * @head: Pointer to "struct tomoyo_io_buffer". 134 * @head: Pointer to "struct tomoyo_io_buffer".
103 * @ptr: Pointer to "struct tomoyo_number_union". 135 * @string: String to print.
104 * 136 *
105 * Returns true on success, false otherwise. 137 * Note that @string has to be kept valid until @head is kfree()d.
138 * This means that char[] allocated on stack memory cannot be passed to
139 * this function. Use tomoyo_io_printf() for char[] allocated on stack memory.
106 */ 140 */
107bool tomoyo_print_number_union(struct tomoyo_io_buffer *head, 141static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
108 const struct tomoyo_number_union *ptr)
109{ 142{
110 unsigned long min; 143 if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) {
111 unsigned long max; 144 head->r.w[head->r.w_pos++] = string;
112 u8 min_type; 145 tomoyo_flush(head);
113 u8 max_type; 146 } else
114 if (!tomoyo_io_printf(head, " ")) 147 WARN_ON(1);
115 return false;
116 if (ptr->is_group)
117 return tomoyo_io_printf(head, "@%s",
118 ptr->group->group_name->name);
119 min_type = ptr->min_type;
120 max_type = ptr->max_type;
121 min = ptr->values[0];
122 max = ptr->values[1];
123 switch (min_type) {
124 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
125 if (!tomoyo_io_printf(head, "0x%lX", min))
126 return false;
127 break;
128 case TOMOYO_VALUE_TYPE_OCTAL:
129 if (!tomoyo_io_printf(head, "0%lo", min))
130 return false;
131 break;
132 default:
133 if (!tomoyo_io_printf(head, "%lu", min))
134 return false;
135 break;
136 }
137 if (min == max && min_type == max_type)
138 return true;
139 switch (max_type) {
140 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
141 return tomoyo_io_printf(head, "-0x%lX", max);
142 case TOMOYO_VALUE_TYPE_OCTAL:
143 return tomoyo_io_printf(head, "-0%lo", max);
144 default:
145 return tomoyo_io_printf(head, "-%lu", max);
146 }
147} 148}
148 149
149/** 150/**
150 * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure. 151 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
151 * 152 *
152 * @head: Pointer to "struct tomoyo_io_buffer". 153 * @head: Pointer to "struct tomoyo_io_buffer".
153 * @fmt: The printf()'s format string, followed by parameters. 154 * @fmt: The printf()'s format string, followed by parameters.
154 *
155 * Returns true if output was written, false otherwise.
156 *
157 * The snprintf() will truncate, but tomoyo_io_printf() won't.
158 */ 155 */
159bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 156void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
160{ 157{
161 va_list args; 158 va_list args;
162 int len; 159 int len;
163 int pos = head->read_avail; 160 int pos = head->r.avail;
164 int size = head->readbuf_size - pos; 161 int size = head->readbuf_size - pos;
165
166 if (size <= 0) 162 if (size <= 0)
167 return false; 163 return;
168 va_start(args, fmt); 164 va_start(args, fmt);
169 len = vsnprintf(head->read_buf + pos, size, fmt, args); 165 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
170 va_end(args); 166 va_end(args);
171 if (pos + len >= head->readbuf_size) 167 if (pos + len >= head->readbuf_size) {
172 return false; 168 WARN_ON(1);
173 head->read_avail += len; 169 return;
174 return true; 170 }
171 head->r.avail += len;
172 tomoyo_set_string(head, head->read_buf + pos);
173}
174
175static void tomoyo_set_space(struct tomoyo_io_buffer *head)
176{
177 tomoyo_set_string(head, " ");
178}
179
180static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
181{
182 tomoyo_set_string(head, "\n");
183 return !head->r.w_pos;
184}
185
186/**
187 * tomoyo_print_name_union - Print a tomoyo_name_union.
188 *
189 * @head: Pointer to "struct tomoyo_io_buffer".
190 * @ptr: Pointer to "struct tomoyo_name_union".
191 */
192static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
193 const struct tomoyo_name_union *ptr)
194{
195 tomoyo_set_space(head);
196 if (ptr->is_group) {
197 tomoyo_set_string(head, "@");
198 tomoyo_set_string(head, ptr->group->group_name->name);
199 } else {
200 tomoyo_set_string(head, ptr->filename->name);
201 }
202}
203
204/**
205 * tomoyo_print_number_union - Print a tomoyo_number_union.
206 *
207 * @head: Pointer to "struct tomoyo_io_buffer".
208 * @ptr: Pointer to "struct tomoyo_number_union".
209 */
210static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
211 const struct tomoyo_number_union *ptr)
212{
213 tomoyo_set_space(head);
214 if (ptr->is_group) {
215 tomoyo_set_string(head, "@");
216 tomoyo_set_string(head, ptr->group->group_name->name);
217 } else {
218 int i;
219 unsigned long min = ptr->values[0];
220 const unsigned long max = ptr->values[1];
221 u8 min_type = ptr->min_type;
222 const u8 max_type = ptr->max_type;
223 char buffer[128];
224 buffer[0] = '\0';
225 for (i = 0; i < 2; i++) {
226 switch (min_type) {
227 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
228 tomoyo_addprintf(buffer, sizeof(buffer),
229 "0x%lX", min);
230 break;
231 case TOMOYO_VALUE_TYPE_OCTAL:
232 tomoyo_addprintf(buffer, sizeof(buffer),
233 "0%lo", min);
234 break;
235 default:
236 tomoyo_addprintf(buffer, sizeof(buffer),
237 "%lu", min);
238 break;
239 }
240 if (min == max && min_type == max_type)
241 break;
242 tomoyo_addprintf(buffer, sizeof(buffer), "-");
243 min_type = max_type;
244 min = max;
245 }
246 tomoyo_io_printf(head, "%s", buffer);
247 }
175} 248}
176 249
177/** 250/**
@@ -334,7 +407,7 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
334 config = TOMOYO_CONFIG_USE_DEFAULT; 407 config = TOMOYO_CONFIG_USE_DEFAULT;
335 } else { 408 } else {
336 for (mode = 3; mode >= 0; mode--) 409 for (mode = 3; mode >= 0; mode--)
337 if (strstr(cp, tomoyo_mode_4[mode])) 410 if (strstr(cp, tomoyo_mode[mode]))
338 /* 411 /*
339 * Update lower 3 bits in order to distinguish 412 * Update lower 3 bits in order to distinguish
340 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. 413 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
@@ -348,6 +421,52 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
348 return 0; 421 return 0;
349} 422}
350 423
424static void tomoyo_print_preference(struct tomoyo_io_buffer *head,
425 const int idx)
426{
427 struct tomoyo_preference *pref = &tomoyo_default_profile.preference;
428 const struct tomoyo_profile *profile = idx >= 0 ?
429 tomoyo_profile_ptr[idx] : NULL;
430 char buffer[16] = "";
431 if (profile) {
432 buffer[sizeof(buffer) - 1] = '\0';
433 snprintf(buffer, sizeof(buffer) - 1, "%u-", idx);
434 }
435 if (profile) {
436 pref = profile->learning;
437 if (pref == &tomoyo_default_profile.preference)
438 goto skip1;
439 }
440 tomoyo_io_printf(head, "%sPREFERENCE::%s={ "
441 "verbose=%s max_entry=%u }\n",
442 buffer, "learning",
443 tomoyo_yesno(pref->learning_verbose),
444 pref->learning_max_entry);
445 skip1:
446 if (profile) {
447 pref = profile->permissive;
448 if (pref == &tomoyo_default_profile.preference)
449 goto skip2;
450 }
451 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
452 buffer, "permissive",
453 tomoyo_yesno(pref->permissive_verbose));
454 skip2:
455 if (profile) {
456 pref = profile->enforcing;
457 if (pref == &tomoyo_default_profile.preference)
458 return;
459 }
460 tomoyo_io_printf(head, "%sPREFERENCE::%s={ verbose=%s }\n",
461 buffer, "enforcing",
462 tomoyo_yesno(pref->enforcing_verbose));
463}
464
465static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
466{
467 tomoyo_io_printf(head, "={ mode=%s }\n", tomoyo_mode[config & 3]);
468}
469
351/** 470/**
352 * tomoyo_read_profile - Read profile table. 471 * tomoyo_read_profile - Read profile table.
353 * 472 *
@@ -355,83 +474,67 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
355 */ 474 */
356static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 475static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
357{ 476{
358 int index; 477 u8 index;
359 if (head->read_eof) 478 const struct tomoyo_profile *profile;
360 return; 479 next:
361 if (head->read_bit) 480 index = head->r.index;
362 goto body; 481 profile = tomoyo_profile_ptr[index];
363 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903"); 482 switch (head->r.step) {
364 tomoyo_io_printf(head, "PREFERENCE::learning={ verbose=%s " 483 case 0:
365 "max_entry=%u }\n", 484 tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
366 tomoyo_yesno(tomoyo_default_profile.preference. 485 tomoyo_print_preference(head, -1);
367 learning_verbose), 486 head->r.step++;
368 tomoyo_default_profile.preference.learning_max_entry); 487 break;
369 tomoyo_io_printf(head, "PREFERENCE::permissive={ verbose=%s }\n", 488 case 1:
370 tomoyo_yesno(tomoyo_default_profile.preference. 489 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
371 permissive_verbose)); 490 head->r.index++)
372 tomoyo_io_printf(head, "PREFERENCE::enforcing={ verbose=%s }\n", 491 if (tomoyo_profile_ptr[head->r.index])
373 tomoyo_yesno(tomoyo_default_profile.preference. 492 break;
374 enforcing_verbose)); 493 if (head->r.index == TOMOYO_MAX_PROFILES)
375 head->read_bit = 1; 494 return;
376 body: 495 head->r.step++;
377 for (index = head->read_step; index < TOMOYO_MAX_PROFILES; index++) { 496 break;
378 bool done; 497 case 2:
379 u8 config; 498 {
380 int i; 499 const struct tomoyo_path_info *comment =
381 int pos; 500 profile->comment;
382 const struct tomoyo_profile *profile 501 tomoyo_io_printf(head, "%u-COMMENT=", index);
383 = tomoyo_profile_ptr[index]; 502 tomoyo_set_string(head, comment ? comment->name : "");
384 const struct tomoyo_path_info *comment; 503 tomoyo_set_lf(head);
385 head->read_step = index; 504 head->r.step++;
386 if (!profile) 505 }
387 continue; 506 break;
388 pos = head->read_avail; 507 case 3:
389 comment = profile->comment; 508 {
390 done = tomoyo_io_printf(head, "%u-COMMENT=%s\n", index, 509 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
391 comment ? comment->name : ""); 510 tomoyo_print_config(head, profile->default_config);
392 if (!done) 511 head->r.bit = 0;
393 goto out; 512 head->r.step++;
394 config = profile->default_config; 513 }
395 if (!tomoyo_io_printf(head, "%u-CONFIG={ mode=%s }\n", index, 514 break;
396 tomoyo_mode_4[config & 3])) 515 case 4:
397 goto out; 516 for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX
398 for (i = 0; i < TOMOYO_MAX_MAC_INDEX + 517 + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
399 TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { 518 const u8 i = head->r.bit;
400 config = profile->config[i]; 519 const u8 config = profile->config[i];
401 if (config == TOMOYO_CONFIG_USE_DEFAULT) 520 if (config == TOMOYO_CONFIG_USE_DEFAULT)
402 continue; 521 continue;
403 if (!tomoyo_io_printf(head, 522 tomoyo_io_printf(head, "%u-%s%s", index, "CONFIG::",
404 "%u-CONFIG::%s={ mode=%s }\n", 523 tomoyo_mac_keywords[i]);
405 index, tomoyo_mac_keywords[i], 524 tomoyo_print_config(head, config);
406 tomoyo_mode_4[config & 3])) 525 head->r.bit++;
407 goto out; 526 break;
527 }
528 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
529 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
530 tomoyo_print_preference(head, index);
531 head->r.index++;
532 head->r.step = 1;
408 } 533 }
409 if (profile->learning != &tomoyo_default_profile.preference &&
410 !tomoyo_io_printf(head, "%u-PREFERENCE::learning={ "
411 "verbose=%s max_entry=%u }\n", index,
412 tomoyo_yesno(profile->preference.
413 learning_verbose),
414 profile->preference.learning_max_entry))
415 goto out;
416 if (profile->permissive != &tomoyo_default_profile.preference
417 && !tomoyo_io_printf(head, "%u-PREFERENCE::permissive={ "
418 "verbose=%s }\n", index,
419 tomoyo_yesno(profile->preference.
420 permissive_verbose)))
421 goto out;
422 if (profile->enforcing != &tomoyo_default_profile.preference &&
423 !tomoyo_io_printf(head, "%u-PREFERENCE::enforcing={ "
424 "verbose=%s }\n", index,
425 tomoyo_yesno(profile->preference.
426 enforcing_verbose)))
427 goto out;
428 continue;
429 out:
430 head->read_avail = pos;
431 break; 534 break;
432 } 535 }
433 if (index == TOMOYO_MAX_PROFILES) 536 if (tomoyo_flush(head))
434 head->read_eof = true; 537 goto next;
435} 538}
436 539
437static bool tomoyo_same_manager_entry(const struct tomoyo_acl_head *a, 540static bool tomoyo_same_manager_entry(const struct tomoyo_acl_head *a,
@@ -507,21 +610,20 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
507 */ 610 */
508static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 611static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
509{ 612{
510 bool done = true; 613 if (head->r.eof)
511
512 if (head->read_eof)
513 return; 614 return;
514 list_for_each_cookie(head->read_var2, 615 list_for_each_cookie(head->r.acl,
515 &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { 616 &tomoyo_policy_list[TOMOYO_ID_MANAGER]) {
516 struct tomoyo_policy_manager_entry *ptr = 617 struct tomoyo_policy_manager_entry *ptr =
517 list_entry(head->read_var2, typeof(*ptr), head.list); 618 list_entry(head->r.acl, typeof(*ptr), head.list);
518 if (ptr->head.is_deleted) 619 if (ptr->head.is_deleted)
519 continue; 620 continue;
520 done = tomoyo_io_printf(head, "%s\n", ptr->manager->name); 621 if (!tomoyo_flush(head))
521 if (!done) 622 return;
522 break; 623 tomoyo_set_string(head, ptr->manager->name);
624 tomoyo_set_lf(head);
523 } 625 }
524 head->read_eof = done; 626 head->r.eof = true;
525} 627}
526 628
527/** 629/**
@@ -595,7 +697,7 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
595 bool global_pid = false; 697 bool global_pid = false;
596 698
597 if (!strcmp(data, "allow_execute")) { 699 if (!strcmp(data, "allow_execute")) {
598 head->print_execute_only = true; 700 head->r.print_execute_only = true;
599 return true; 701 return true;
600 } 702 }
601 if (sscanf(data, "pid=%u", &pid) == 1 || 703 if (sscanf(data, "pid=%u", &pid) == 1 ||
@@ -620,14 +722,11 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
620 /* Accessing read_buf is safe because head->io_sem is held. */ 722 /* Accessing read_buf is safe because head->io_sem is held. */
621 if (!head->read_buf) 723 if (!head->read_buf)
622 return true; /* Do nothing if open(O_WRONLY). */ 724 return true; /* Do nothing if open(O_WRONLY). */
623 head->read_avail = 0; 725 memset(&head->r, 0, sizeof(head->r));
726 head->r.print_this_domain_only = true;
727 head->r.eof = !domain;
728 head->r.domain = &domain->list;
624 tomoyo_io_printf(head, "# select %s\n", data); 729 tomoyo_io_printf(head, "# select %s\n", data);
625 head->read_single_domain = true;
626 head->read_eof = !domain;
627 head->read_var1 = &domain->list;
628 head->read_var2 = NULL;
629 head->read_bit = 0;
630 head->read_step = 0;
631 if (domain && domain->is_deleted) 730 if (domain && domain->is_deleted)
632 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 731 tomoyo_io_printf(head, "# This is a deleted domain.\n");
633 return true; 732 return true;
@@ -773,20 +872,22 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
773 struct tomoyo_acl_info *acl) 872 struct tomoyo_acl_info *acl)
774{ 873{
775 const u8 acl_type = acl->type; 874 const u8 acl_type = acl->type;
776 u8 bit = head->read_bit; 875 u8 bit;
777 int pos = head->read_avail;
778 876
779 if (acl->is_deleted) 877 if (acl->is_deleted)
780 return true; 878 return true;
781 next: 879 next:
782 if (acl_type == TOMOYO_TYPE_PATH_ACL) { 880 bit = head->r.bit;
881 if (!tomoyo_flush(head))
882 return false;
883 else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
783 struct tomoyo_path_acl *ptr = 884 struct tomoyo_path_acl *ptr =
784 container_of(acl, typeof(*ptr), head); 885 container_of(acl, typeof(*ptr), head);
785 const u16 perm = ptr->perm; 886 const u16 perm = ptr->perm;
786 for ( ; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 887 for ( ; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
787 if (!(perm & (1 << bit))) 888 if (!(perm & (1 << bit)))
788 continue; 889 continue;
789 if (head->print_execute_only && 890 if (head->r.print_execute_only &&
790 bit != TOMOYO_TYPE_EXECUTE) 891 bit != TOMOYO_TYPE_EXECUTE)
791 continue; 892 continue;
792 /* Print "read/write" instead of "read" and "write". */ 893 /* Print "read/write" instead of "read" and "write". */
@@ -798,11 +899,9 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
798 } 899 }
799 if (bit >= TOMOYO_MAX_PATH_OPERATION) 900 if (bit >= TOMOYO_MAX_PATH_OPERATION)
800 goto done; 901 goto done;
801 if (!tomoyo_io_printf(head, "allow_%s ", 902 tomoyo_io_printf(head, "allow_%s", tomoyo_path_keyword[bit]);
802 tomoyo_path_keyword[bit]) || 903 tomoyo_print_name_union(head, &ptr->name);
803 !tomoyo_print_name_union(head, &ptr->name)) 904 } else if (head->r.print_execute_only) {
804 goto out;
805 } else if (head->print_execute_only) {
806 return true; 905 return true;
807 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 906 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
808 struct tomoyo_path2_acl *ptr = 907 struct tomoyo_path2_acl *ptr =
@@ -810,58 +909,69 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
810 bit = tomoyo_fns(ptr->perm, bit); 909 bit = tomoyo_fns(ptr->perm, bit);
811 if (bit >= TOMOYO_MAX_PATH2_OPERATION) 910 if (bit >= TOMOYO_MAX_PATH2_OPERATION)
812 goto done; 911 goto done;
813 if (!tomoyo_io_printf(head, "allow_%s ", 912 tomoyo_io_printf(head, "allow_%s", tomoyo_path2_keyword[bit]);
814 tomoyo_path2_keyword[bit]) || 913 tomoyo_print_name_union(head, &ptr->name1);
815 !tomoyo_print_name_union(head, &ptr->name1) || 914 tomoyo_print_name_union(head, &ptr->name2);
816 !tomoyo_print_name_union(head, &ptr->name2))
817 goto out;
818 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { 915 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
819 struct tomoyo_path_number_acl *ptr = 916 struct tomoyo_path_number_acl *ptr =
820 container_of(acl, typeof(*ptr), head); 917 container_of(acl, typeof(*ptr), head);
821 bit = tomoyo_fns(ptr->perm, bit); 918 bit = tomoyo_fns(ptr->perm, bit);
822 if (bit >= TOMOYO_MAX_PATH_NUMBER_OPERATION) 919 if (bit >= TOMOYO_MAX_PATH_NUMBER_OPERATION)
823 goto done; 920 goto done;
824 if (!tomoyo_io_printf(head, "allow_%s", 921 tomoyo_io_printf(head, "allow_%s",
825 tomoyo_path_number_keyword[bit]) || 922 tomoyo_path_number_keyword[bit]);
826 !tomoyo_print_name_union(head, &ptr->name) || 923 tomoyo_print_name_union(head, &ptr->name);
827 !tomoyo_print_number_union(head, &ptr->number)) 924 tomoyo_print_number_union(head, &ptr->number);
828 goto out;
829 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { 925 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
830 struct tomoyo_mkdev_acl *ptr = 926 struct tomoyo_mkdev_acl *ptr =
831 container_of(acl, typeof(*ptr), head); 927 container_of(acl, typeof(*ptr), head);
832 bit = tomoyo_fns(ptr->perm, bit); 928 bit = tomoyo_fns(ptr->perm, bit);
833 if (bit >= TOMOYO_MAX_MKDEV_OPERATION) 929 if (bit >= TOMOYO_MAX_MKDEV_OPERATION)
834 goto done; 930 goto done;
835 if (!tomoyo_io_printf(head, "allow_%s", 931 tomoyo_io_printf(head, "allow_%s", tomoyo_mkdev_keyword[bit]);
836 tomoyo_mkdev_keyword[bit]) || 932 tomoyo_print_name_union(head, &ptr->name);
837 !tomoyo_print_name_union(head, &ptr->name) || 933 tomoyo_print_number_union(head, &ptr->mode);
838 !tomoyo_print_number_union(head, &ptr->mode) || 934 tomoyo_print_number_union(head, &ptr->major);
839 !tomoyo_print_number_union(head, &ptr->major) || 935 tomoyo_print_number_union(head, &ptr->minor);
840 !tomoyo_print_number_union(head, &ptr->minor))
841 goto out;
842 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 936 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
843 struct tomoyo_mount_acl *ptr = 937 struct tomoyo_mount_acl *ptr =
844 container_of(acl, typeof(*ptr), head); 938 container_of(acl, typeof(*ptr), head);
845 if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) || 939 tomoyo_io_printf(head, "allow_mount");
846 !tomoyo_print_name_union(head, &ptr->dev_name) || 940 tomoyo_print_name_union(head, &ptr->dev_name);
847 !tomoyo_print_name_union(head, &ptr->dir_name) || 941 tomoyo_print_name_union(head, &ptr->dir_name);
848 !tomoyo_print_name_union(head, &ptr->fs_type) || 942 tomoyo_print_name_union(head, &ptr->fs_type);
849 !tomoyo_print_number_union(head, &ptr->flags)) 943 tomoyo_print_number_union(head, &ptr->flags);
850 goto out;
851 } 944 }
852 if (!tomoyo_io_printf(head, "\n")) 945 head->r.bit = bit + 1;
853 goto out; 946 tomoyo_io_printf(head, "\n");
854 head->read_bit = bit; 947 if (acl_type != TOMOYO_TYPE_MOUNT_ACL)
855 if (acl_type != TOMOYO_TYPE_MOUNT_ACL) {
856 bit++;
857 goto next; 948 goto next;
858 }
859 done: 949 done:
860 head->read_bit = 0; 950 head->r.bit = 0;
951 return true;
952}
953
954/**
955 * tomoyo_read_domain2 - Read domain policy.
956 *
957 * @head: Pointer to "struct tomoyo_io_buffer".
958 * @domain: Pointer to "struct tomoyo_domain_info".
959 *
960 * Caller holds tomoyo_read_lock().
961 *
962 * Returns true on success, false otherwise.
963 */
964static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
965 struct tomoyo_domain_info *domain)
966{
967 list_for_each_cookie(head->r.acl, &domain->acl_info_list) {
968 struct tomoyo_acl_info *ptr =
969 list_entry(head->r.acl, typeof(*ptr), list);
970 if (!tomoyo_print_entry(head, ptr))
971 return false;
972 }
973 head->r.acl = NULL;
861 return true; 974 return true;
862 out:
863 head->read_avail = pos;
864 return false;
865} 975}
866 976
867/** 977/**
@@ -873,64 +983,48 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
873 */ 983 */
874static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 984static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
875{ 985{
876 bool done = true; 986 if (head->r.eof)
877
878 if (head->read_eof)
879 return; 987 return;
880 if (head->read_step == 0) 988 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
881 head->read_step = 1;
882 list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
883 struct tomoyo_domain_info *domain = 989 struct tomoyo_domain_info *domain =
884 list_entry(head->read_var1, typeof(*domain), list); 990 list_entry(head->r.domain, typeof(*domain), list);
885 const char *quota_exceeded = ""; 991 switch (head->r.step) {
886 const char *transition_failed = ""; 992 case 0:
887 const char *ignore_global_allow_read = ""; 993 if (domain->is_deleted &&
888 if (head->read_step != 1) 994 !head->r.print_this_domain_only)
889 goto acl_loop; 995 continue;
890 if (domain->is_deleted && !head->read_single_domain) 996 /* Print domainname and flags. */
891 continue; 997 tomoyo_set_string(head, domain->domainname->name);
892 /* Print domainname and flags. */ 998 tomoyo_set_lf(head);
893 if (domain->quota_warned) 999 tomoyo_io_printf(head,
894 quota_exceeded = "quota_exceeded\n"; 1000 TOMOYO_KEYWORD_USE_PROFILE "%u\n",
895 if (domain->transition_failed) 1001 domain->profile);
896 transition_failed = "transition_failed\n"; 1002 if (domain->quota_warned)
897 if (domain->ignore_global_allow_read) 1003 tomoyo_set_string(head, "quota_exceeded\n");
898 ignore_global_allow_read 1004 if (domain->transition_failed)
899 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1005 tomoyo_set_string(head, "transition_failed\n");
900 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE 1006 if (domain->ignore_global_allow_read)
901 "%u\n%s%s%s\n", 1007 tomoyo_set_string(head,
902 domain->domainname->name, 1008 TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ
903 domain->profile, quota_exceeded, 1009 "\n");
904 transition_failed, 1010 head->r.step++;
905 ignore_global_allow_read); 1011 tomoyo_set_lf(head);
906 if (!done) 1012 /* fall through */
907 break; 1013 case 1:
908 head->read_step = 2; 1014 if (!tomoyo_read_domain2(head, domain))
909acl_loop: 1015 return;
910 if (head->read_step == 3) 1016 head->r.step++;
911 goto tail_mark; 1017 if (!tomoyo_set_lf(head))
912 /* Print ACL entries in the domain. */ 1018 return;
913 list_for_each_cookie(head->read_var2, 1019 /* fall through */
914 &domain->acl_info_list) { 1020 case 2:
915 struct tomoyo_acl_info *ptr = 1021 head->r.step = 0;
916 list_entry(head->read_var2, typeof(*ptr), list); 1022 if (head->r.print_this_domain_only)
917 done = tomoyo_print_entry(head, ptr); 1023 goto done;
918 if (!done)
919 break;
920 } 1024 }
921 if (!done)
922 break;
923 head->read_var2 = NULL;
924 head->read_step = 3;
925tail_mark:
926 done = tomoyo_io_printf(head, "\n");
927 if (!done)
928 break;
929 head->read_step = 1;
930 if (head->read_single_domain)
931 break;
932 } 1025 }
933 head->read_eof = done; 1026 done:
1027 head->r.eof = true;
934} 1028}
935 1029
936/** 1030/**
@@ -984,21 +1078,20 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
984 */ 1078 */
985static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1079static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
986{ 1080{
987 bool done = true; 1081 if (head->r.eof)
988
989 if (head->read_eof)
990 return; 1082 return;
991 list_for_each_cookie(head->read_var1, &tomoyo_domain_list) { 1083 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
992 struct tomoyo_domain_info *domain = 1084 struct tomoyo_domain_info *domain =
993 list_entry(head->read_var1, typeof(*domain), list); 1085 list_entry(head->r.domain, typeof(*domain), list);
994 if (domain->is_deleted) 1086 if (domain->is_deleted)
995 continue; 1087 continue;
996 done = tomoyo_io_printf(head, "%u %s\n", domain->profile, 1088 if (!tomoyo_flush(head))
997 domain->domainname->name); 1089 return;
998 if (!done) 1090 tomoyo_io_printf(head, "%u ", domain->profile);
999 break; 1091 tomoyo_set_string(head, domain->domainname->name);
1092 tomoyo_set_lf(head);
1000 } 1093 }
1001 head->read_eof = done; 1094 head->r.eof = true;
1002} 1095}
1003 1096
1004/** 1097/**
@@ -1010,11 +1103,7 @@ static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1010 */ 1103 */
1011static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1104static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1012{ 1105{
1013 unsigned long pid; 1106 head->r.eof = false;
1014 /* No error check. */
1015 strict_strtoul(head->write_buf, 10, &pid);
1016 head->read_step = (int) pid;
1017 head->read_eof = false;
1018 return 0; 1107 return 0;
1019} 1108}
1020 1109
@@ -1030,22 +1119,37 @@ static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1030 */ 1119 */
1031static void tomoyo_read_pid(struct tomoyo_io_buffer *head) 1120static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1032{ 1121{
1033 if (head->read_avail == 0 && !head->read_eof) { 1122 char *buf = head->write_buf;
1034 const int pid = head->read_step; 1123 bool global_pid = false;
1035 struct task_struct *p; 1124 unsigned int pid;
1036 struct tomoyo_domain_info *domain = NULL; 1125 struct task_struct *p;
1037 rcu_read_lock(); 1126 struct tomoyo_domain_info *domain = NULL;
1038 read_lock(&tasklist_lock); 1127
1039 p = find_task_by_vpid(pid); 1128 /* Accessing write_buf is safe because head->io_sem is held. */
1040 if (p) 1129 if (!buf) {
1041 domain = tomoyo_real_domain(p); 1130 head->r.eof = true;
1042 read_unlock(&tasklist_lock); 1131 return; /* Do nothing if open(O_RDONLY). */
1043 rcu_read_unlock();
1044 if (domain)
1045 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1046 domain->domainname->name);
1047 head->read_eof = true;
1048 } 1132 }
1133 if (head->r.w_pos || head->r.eof)
1134 return;
1135 head->r.eof = true;
1136 if (tomoyo_str_starts(&buf, "global-pid "))
1137 global_pid = true;
1138 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1139 rcu_read_lock();
1140 read_lock(&tasklist_lock);
1141 if (global_pid)
1142 p = find_task_by_pid_ns(pid, &init_pid_ns);
1143 else
1144 p = find_task_by_vpid(pid);
1145 if (p)
1146 domain = tomoyo_real_domain(p);
1147 read_unlock(&tasklist_lock);
1148 rcu_read_unlock();
1149 if (!domain)
1150 return;
1151 tomoyo_io_printf(head, "%u %u ", pid, domain->profile);
1152 tomoyo_set_string(head, domain->domainname->name);
1049} 1153}
1050 1154
1051static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1155static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
@@ -1092,40 +1196,6 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1092 return -EINVAL; 1196 return -EINVAL;
1093} 1197}
1094 1198
1095static void tomoyo_print_number(char *buffer, int buffer_len,
1096 const struct tomoyo_number_union *ptr)
1097{
1098 int i;
1099 unsigned long min = ptr->values[0];
1100 const unsigned long max = ptr->values[1];
1101 u8 min_type = ptr->min_type;
1102 const u8 max_type = ptr->max_type;
1103 memset(buffer, 0, buffer_len);
1104 buffer_len -= 2;
1105 for (i = 0; i < 2; i++) {
1106 int len;
1107 switch (min_type) {
1108 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
1109 snprintf(buffer, buffer_len, "0x%lX", min);
1110 break;
1111 case TOMOYO_VALUE_TYPE_OCTAL:
1112 snprintf(buffer, buffer_len, "0%lo", min);
1113 break;
1114 default:
1115 snprintf(buffer, buffer_len, "%lu", min);
1116 break;
1117 }
1118 if (min == max && min_type == max_type)
1119 break;
1120 len = strlen(buffer);
1121 buffer[len++] = '-';
1122 buffer += len;
1123 buffer_len -= len;
1124 min_type = max_type;
1125 min = max;
1126 }
1127}
1128
1129static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1199static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1130 [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP, 1200 [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP,
1131 [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP 1201 [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP
@@ -1143,37 +1213,34 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1143 */ 1213 */
1144static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1214static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1145{ 1215{
1146 const char *w[3] = { "", "", "" }; 1216 list_for_each_cookie(head->r.group, &tomoyo_group_list[idx]) {
1147 w[0] = tomoyo_group_name[idx];
1148 list_for_each_cookie(head->read_var1, &tomoyo_group_list[idx]) {
1149 struct tomoyo_group *group = 1217 struct tomoyo_group *group =
1150 list_entry(head->read_var1, typeof(*group), list); 1218 list_entry(head->r.group, typeof(*group), list);
1151 w[1] = group->group_name->name; 1219 list_for_each_cookie(head->r.acl, &group->member_list) {
1152 list_for_each_cookie(head->read_var2, &group->member_list) {
1153 char buffer[128];
1154 struct tomoyo_acl_head *ptr = 1220 struct tomoyo_acl_head *ptr =
1155 list_entry(head->read_var2, typeof(*ptr), list); 1221 list_entry(head->r.acl, typeof(*ptr), list);
1156 if (ptr->is_deleted) 1222 if (ptr->is_deleted)
1157 continue; 1223 continue;
1224 if (!tomoyo_flush(head))
1225 return false;
1226 tomoyo_set_string(head, tomoyo_group_name[idx]);
1227 tomoyo_set_string(head, group->group_name->name);
1158 if (idx == TOMOYO_PATH_GROUP) { 1228 if (idx == TOMOYO_PATH_GROUP) {
1159 w[2] = container_of(ptr, 1229 tomoyo_set_space(head);
1160 struct tomoyo_path_group, 1230 tomoyo_set_string(head, container_of
1161 head)->member_name->name; 1231 (ptr, struct tomoyo_path_group,
1232 head)->member_name->name);
1162 } else if (idx == TOMOYO_NUMBER_GROUP) { 1233 } else if (idx == TOMOYO_NUMBER_GROUP) {
1163 tomoyo_print_number(buffer, sizeof(buffer), 1234 tomoyo_print_number_union(head, &container_of
1164 &container_of 1235 (ptr,
1165 (ptr, struct 1236 struct tomoyo_number_group,
1166 tomoyo_number_group, 1237 head)->number);
1167 head)->number);
1168 w[2] = buffer;
1169 } 1238 }
1170 if (!tomoyo_io_printf(head, "%s%s %s\n", w[0], w[1], 1239 tomoyo_set_lf(head);
1171 w[2]))
1172 return false;
1173 } 1240 }
1174 head->read_var2 = NULL; 1241 head->r.acl = NULL;
1175 } 1242 }
1176 head->read_var1 = NULL; 1243 head->r.group = NULL;
1177 return true; 1244 return true;
1178} 1245}
1179 1246
@@ -1189,68 +1256,78 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1189 */ 1256 */
1190static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1257static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1191{ 1258{
1192 list_for_each_cookie(head->read_var2, &tomoyo_policy_list[idx]) { 1259 list_for_each_cookie(head->r.acl, &tomoyo_policy_list[idx]) {
1193 const char *w[4] = { "", "", "", "" };
1194 struct tomoyo_acl_head *acl = 1260 struct tomoyo_acl_head *acl =
1195 container_of(head->read_var2, typeof(*acl), list); 1261 container_of(head->r.acl, typeof(*acl), list);
1196 if (acl->is_deleted) 1262 if (acl->is_deleted)
1197 continue; 1263 continue;
1264 if (!tomoyo_flush(head))
1265 return false;
1198 switch (idx) { 1266 switch (idx) {
1199 case TOMOYO_ID_TRANSITION_CONTROL: 1267 case TOMOYO_ID_TRANSITION_CONTROL:
1200 { 1268 {
1201 struct tomoyo_transition_control *ptr = 1269 struct tomoyo_transition_control *ptr =
1202 container_of(acl, typeof(*ptr), head); 1270 container_of(acl, typeof(*ptr), head);
1203 w[0] = tomoyo_transition_type[ptr->type]; 1271 tomoyo_set_string(head,
1272 tomoyo_transition_type
1273 [ptr->type]);
1204 if (ptr->program) 1274 if (ptr->program)
1205 w[1] = ptr->program->name; 1275 tomoyo_set_string(head,
1276 ptr->program->name);
1277 if (ptr->program && ptr->domainname)
1278 tomoyo_set_string(head, " from ");
1206 if (ptr->domainname) 1279 if (ptr->domainname)
1207 w[3] = ptr->domainname->name; 1280 tomoyo_set_string(head,
1208 if (w[1][0] && w[3][0]) 1281 ptr->domainname->
1209 w[2] = " from "; 1282 name);
1210 } 1283 }
1211 break; 1284 break;
1212 case TOMOYO_ID_GLOBALLY_READABLE: 1285 case TOMOYO_ID_GLOBALLY_READABLE:
1213 { 1286 {
1214 struct tomoyo_globally_readable_file_entry *ptr 1287 struct tomoyo_globally_readable_file_entry *ptr
1215 = container_of(acl, typeof(*ptr), head); 1288 = container_of(acl, typeof(*ptr), head);
1216 w[0] = TOMOYO_KEYWORD_ALLOW_READ; 1289 tomoyo_set_string(head,
1217 w[1] = ptr->filename->name; 1290 TOMOYO_KEYWORD_ALLOW_READ);
1291 tomoyo_set_string(head, ptr->filename->name);
1218 } 1292 }
1219 break; 1293 break;
1220 case TOMOYO_ID_AGGREGATOR: 1294 case TOMOYO_ID_AGGREGATOR:
1221 { 1295 {
1222 struct tomoyo_aggregator_entry *ptr = 1296 struct tomoyo_aggregator_entry *ptr =
1223 container_of(acl, typeof(*ptr), head); 1297 container_of(acl, typeof(*ptr), head);
1224 w[0] = TOMOYO_KEYWORD_AGGREGATOR; 1298 tomoyo_set_string(head,
1225 w[1] = ptr->original_name->name; 1299 TOMOYO_KEYWORD_AGGREGATOR);
1226 w[2] = " "; 1300 tomoyo_set_string(head,
1227 w[3] = ptr->aggregated_name->name; 1301 ptr->original_name->name);
1302 tomoyo_set_space(head);
1303 tomoyo_set_string(head,
1304 ptr->aggregated_name->name);
1228 } 1305 }
1229 break; 1306 break;
1230 case TOMOYO_ID_PATTERN: 1307 case TOMOYO_ID_PATTERN:
1231 { 1308 {
1232 struct tomoyo_pattern_entry *ptr = 1309 struct tomoyo_pattern_entry *ptr =
1233 container_of(acl, typeof(*ptr), head); 1310 container_of(acl, typeof(*ptr), head);
1234 w[0] = TOMOYO_KEYWORD_FILE_PATTERN; 1311 tomoyo_set_string(head,
1235 w[1] = ptr->pattern->name; 1312 TOMOYO_KEYWORD_FILE_PATTERN);
1313 tomoyo_set_string(head, ptr->pattern->name);
1236 } 1314 }
1237 break; 1315 break;
1238 case TOMOYO_ID_NO_REWRITE: 1316 case TOMOYO_ID_NO_REWRITE:
1239 { 1317 {
1240 struct tomoyo_no_rewrite_entry *ptr = 1318 struct tomoyo_no_rewrite_entry *ptr =
1241 container_of(acl, typeof(*ptr), head); 1319 container_of(acl, typeof(*ptr), head);
1242 w[0] = TOMOYO_KEYWORD_DENY_REWRITE; 1320 tomoyo_set_string(head,
1243 w[1] = ptr->pattern->name; 1321 TOMOYO_KEYWORD_DENY_REWRITE);
1322 tomoyo_set_string(head, ptr->pattern->name);
1244 } 1323 }
1245 break; 1324 break;
1246 default: 1325 default:
1247 continue; 1326 continue;
1248 } 1327 }
1249 if (!tomoyo_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2], 1328 tomoyo_set_lf(head);
1250 w[3]))
1251 return false;
1252 } 1329 }
1253 head->read_var2 = NULL; 1330 head->r.acl = NULL;
1254 return true; 1331 return true;
1255} 1332}
1256 1333
@@ -1263,19 +1340,19 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1263 */ 1340 */
1264static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1341static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1265{ 1342{
1266 if (head->read_eof) 1343 if (head->r.eof)
1267 return; 1344 return;
1268 while (head->read_step < TOMOYO_MAX_POLICY && 1345 while (head->r.step < TOMOYO_MAX_POLICY &&
1269 tomoyo_read_policy(head, head->read_step)) 1346 tomoyo_read_policy(head, head->r.step))
1270 head->read_step++; 1347 head->r.step++;
1271 if (head->read_step < TOMOYO_MAX_POLICY) 1348 if (head->r.step < TOMOYO_MAX_POLICY)
1272 return; 1349 return;
1273 while (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP && 1350 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
1274 tomoyo_read_group(head, head->read_step - TOMOYO_MAX_POLICY)) 1351 tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY))
1275 head->read_step++; 1352 head->r.step++;
1276 if (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) 1353 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1277 return; 1354 return;
1278 head->read_eof = true; 1355 head->r.eof = true;
1279} 1356}
1280 1357
1281/** 1358/**
@@ -1290,9 +1367,6 @@ static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1290 */ 1367 */
1291static char *tomoyo_print_header(struct tomoyo_request_info *r) 1368static char *tomoyo_print_header(struct tomoyo_request_info *r)
1292{ 1369{
1293 static const char *tomoyo_mode_4[4] = {
1294 "disabled", "learning", "permissive", "enforcing"
1295 };
1296 struct timeval tv; 1370 struct timeval tv;
1297 const pid_t gpid = task_pid_nr(current); 1371 const pid_t gpid = task_pid_nr(current);
1298 static const int tomoyo_buffer_len = 4096; 1372 static const int tomoyo_buffer_len = 4096;
@@ -1304,7 +1378,7 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r)
1304 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)" 1378 "#timestamp=%lu profile=%u mode=%s (global-pid=%u)"
1305 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u" 1379 " task={ pid=%u ppid=%u uid=%u gid=%u euid=%u"
1306 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }", 1380 " egid=%u suid=%u sgid=%u fsuid=%u fsgid=%u }",
1307 tv.tv_sec, r->profile, tomoyo_mode_4[r->mode], gpid, 1381 tv.tv_sec, r->profile, tomoyo_mode[r->mode], gpid,
1308 (pid_t) sys_getpid(), (pid_t) sys_getppid(), 1382 (pid_t) sys_getpid(), (pid_t) sys_getppid(),
1309 current_uid(), current_gid(), current_euid(), 1383 current_uid(), current_gid(), current_euid(),
1310 current_egid(), current_suid(), current_sgid(), 1384 current_egid(), current_suid(), current_sgid(),
@@ -1536,27 +1610,26 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1536 int pos = 0; 1610 int pos = 0;
1537 int len = 0; 1611 int len = 0;
1538 char *buf; 1612 char *buf;
1539 if (head->read_avail) 1613 if (head->r.w_pos)
1540 return; 1614 return;
1541 if (head->read_buf) { 1615 if (head->read_buf) {
1542 kfree(head->read_buf); 1616 kfree(head->read_buf);
1543 head->read_buf = NULL; 1617 head->read_buf = NULL;
1544 head->readbuf_size = 0;
1545 } 1618 }
1546 spin_lock(&tomoyo_query_list_lock); 1619 spin_lock(&tomoyo_query_list_lock);
1547 list_for_each(tmp, &tomoyo_query_list) { 1620 list_for_each(tmp, &tomoyo_query_list) {
1548 struct tomoyo_query_entry *ptr 1621 struct tomoyo_query_entry *ptr =
1549 = list_entry(tmp, struct tomoyo_query_entry, list); 1622 list_entry(tmp, typeof(*ptr), list);
1550 if (ptr->answer) 1623 if (ptr->answer)
1551 continue; 1624 continue;
1552 if (pos++ != head->read_step) 1625 if (pos++ != head->r.query_index)
1553 continue; 1626 continue;
1554 len = ptr->query_len; 1627 len = ptr->query_len;
1555 break; 1628 break;
1556 } 1629 }
1557 spin_unlock(&tomoyo_query_list_lock); 1630 spin_unlock(&tomoyo_query_list_lock);
1558 if (!len) { 1631 if (!len) {
1559 head->read_step = 0; 1632 head->r.query_index = 0;
1560 return; 1633 return;
1561 } 1634 }
1562 buf = kzalloc(len, GFP_NOFS); 1635 buf = kzalloc(len, GFP_NOFS);
@@ -1565,11 +1638,11 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1565 pos = 0; 1638 pos = 0;
1566 spin_lock(&tomoyo_query_list_lock); 1639 spin_lock(&tomoyo_query_list_lock);
1567 list_for_each(tmp, &tomoyo_query_list) { 1640 list_for_each(tmp, &tomoyo_query_list) {
1568 struct tomoyo_query_entry *ptr 1641 struct tomoyo_query_entry *ptr =
1569 = list_entry(tmp, struct tomoyo_query_entry, list); 1642 list_entry(tmp, typeof(*ptr), list);
1570 if (ptr->answer) 1643 if (ptr->answer)
1571 continue; 1644 continue;
1572 if (pos++ != head->read_step) 1645 if (pos++ != head->r.query_index)
1573 continue; 1646 continue;
1574 /* 1647 /*
1575 * Some query can be skipped because tomoyo_query_list 1648 * Some query can be skipped because tomoyo_query_list
@@ -1581,10 +1654,9 @@ static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1581 } 1654 }
1582 spin_unlock(&tomoyo_query_list_lock); 1655 spin_unlock(&tomoyo_query_list_lock);
1583 if (buf[0]) { 1656 if (buf[0]) {
1584 head->read_avail = len;
1585 head->readbuf_size = head->read_avail;
1586 head->read_buf = buf; 1657 head->read_buf = buf;
1587 head->read_step++; 1658 head->r.w[head->r.w_pos++] = buf;
1659 head->r.query_index++;
1588 } else { 1660 } else {
1589 kfree(buf); 1661 kfree(buf);
1590 } 1662 }
@@ -1635,9 +1707,9 @@ static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
1635 */ 1707 */
1636static void tomoyo_read_version(struct tomoyo_io_buffer *head) 1708static void tomoyo_read_version(struct tomoyo_io_buffer *head)
1637{ 1709{
1638 if (!head->read_eof) { 1710 if (!head->r.eof) {
1639 tomoyo_io_printf(head, "2.3.0-pre"); 1711 tomoyo_io_printf(head, "2.3.0-pre");
1640 head->read_eof = true; 1712 head->r.eof = true;
1641 } 1713 }
1642} 1714}
1643 1715
@@ -1650,14 +1722,14 @@ static void tomoyo_read_version(struct tomoyo_io_buffer *head)
1650 */ 1722 */
1651static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head) 1723static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1652{ 1724{
1653 if (!head->read_eof) { 1725 if (!head->r.eof) {
1654 /* 1726 /*
1655 * tomoyo_domain()->domainname != NULL 1727 * tomoyo_domain()->domainname != NULL
1656 * because every process belongs to a domain and 1728 * because every process belongs to a domain and
1657 * the domain's name cannot be NULL. 1729 * the domain's name cannot be NULL.
1658 */ 1730 */
1659 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); 1731 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
1660 head->read_eof = true; 1732 head->r.eof = true;
1661 } 1733 }
1662} 1734}
1663 1735
@@ -1817,33 +1889,20 @@ int tomoyo_poll_control(struct file *file, poll_table *wait)
1817int tomoyo_read_control(struct file *file, char __user *buffer, 1889int tomoyo_read_control(struct file *file, char __user *buffer,
1818 const int buffer_len) 1890 const int buffer_len)
1819{ 1891{
1820 int len = 0; 1892 int len;
1821 struct tomoyo_io_buffer *head = file->private_data; 1893 struct tomoyo_io_buffer *head = file->private_data;
1822 char *cp;
1823 1894
1824 if (!head->read) 1895 if (!head->read)
1825 return -ENOSYS; 1896 return -ENOSYS;
1826 if (mutex_lock_interruptible(&head->io_sem)) 1897 if (mutex_lock_interruptible(&head->io_sem))
1827 return -EINTR; 1898 return -EINTR;
1828 /* Call the policy handler. */ 1899 head->read_user_buf = buffer;
1829 head->read(head); 1900 head->read_user_buf_avail = buffer_len;
1830 if (len < 0) 1901 if (tomoyo_flush(head))
1831 goto out; 1902 /* Call the policy handler. */
1832 /* Write to buffer. */ 1903 head->read(head);
1833 len = head->read_avail; 1904 tomoyo_flush(head);
1834 if (len > buffer_len) 1905 len = head->read_user_buf - buffer;
1835 len = buffer_len;
1836 if (!len)
1837 goto out;
1838 /* head->read_buf changes by some functions. */
1839 cp = head->read_buf;
1840 if (copy_to_user(buffer, cp, len)) {
1841 len = -EFAULT;
1842 goto out;
1843 }
1844 head->read_avail -= len;
1845 memmove(cp, cp + len, head->read_avail);
1846 out:
1847 mutex_unlock(&head->io_sem); 1906 mutex_unlock(&head->io_sem);
1848 return len; 1907 return len;
1849} 1908}
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 */
550struct tomoyo_io_buffer { 533struct 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,
738bool tomoyo_compare_number_union(const unsigned long value, 722bool tomoyo_compare_number_union(const unsigned long value,
739 const struct tomoyo_number_union *ptr); 723 const struct tomoyo_number_union *ptr);
740int tomoyo_get_mode(const u8 profile, const u8 index); 724int tomoyo_get_mode(const u8 profile, const u8 index);
741/* Transactional sprintf() for policy dump. */ 725void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
742bool 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. */
745bool tomoyo_correct_domain(const unsigned char *domainname); 728bool tomoyo_correct_domain(const unsigned char *domainname);
@@ -761,8 +744,6 @@ bool tomoyo_number_matches_group(const unsigned long min,
761bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 744bool 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
764bool tomoyo_print_number_union(struct tomoyo_io_buffer *head,
765 const struct tomoyo_number_union *ptr);
766bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); 747bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num);
767/* Tokenize a line. */ 748/* Tokenize a line. */
768bool tomoyo_tokenize(char *buffer, char *w[], size_t size); 749bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 95a77599ff98..a4aba4d9ca2e 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -234,7 +234,7 @@ unsigned int tomoyo_quota_for_query;
234 */ 234 */
235void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 235void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
236{ 236{
237 if (!head->read_eof) { 237 if (!head->r.eof) {
238 const unsigned int policy 238 const unsigned int policy
239 = atomic_read(&tomoyo_policy_memory_size); 239 = atomic_read(&tomoyo_policy_memory_size);
240 const unsigned int query = tomoyo_query_memory_size; 240 const unsigned int query = tomoyo_query_memory_size;
@@ -258,7 +258,7 @@ void tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
258 tomoyo_io_printf(head, "Query lists: %10u%s\n", query, 258 tomoyo_io_printf(head, "Query lists: %10u%s\n", query,
259 buffer); 259 buffer);
260 tomoyo_io_printf(head, "Total: %10u\n", policy + query); 260 tomoyo_io_printf(head, "Total: %10u\n", policy + query);
261 head->read_eof = true; 261 head->r.eof = true;
262 } 262 }
263} 263}
264 264