]> bbs.cooldavid.org Git - net-next-2.6.git/blob - security/tomoyo/file.c
727cc723f87d5d2897279ae4fa18800663fd6755
[net-next-2.6.git] / security / tomoyo / file.c
1 /*
2  * security/tomoyo/file.c
3  *
4  * Implementation of the Domain-Based Mandatory Access Control.
5  *
6  * Copyright (C) 2005-2009  NTT DATA CORPORATION
7  *
8  * Version: 2.2.0   2009/04/01
9  *
10  */
11
12 #include "common.h"
13 #include <linux/slab.h>
14
15 /* Keyword array for operations with one pathname. */
16 static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
17         [TOMOYO_TYPE_READ_WRITE] = "read/write",
18         [TOMOYO_TYPE_EXECUTE]    = "execute",
19         [TOMOYO_TYPE_READ]       = "read",
20         [TOMOYO_TYPE_WRITE]      = "write",
21         [TOMOYO_TYPE_UNLINK]     = "unlink",
22         [TOMOYO_TYPE_RMDIR]      = "rmdir",
23         [TOMOYO_TYPE_TRUNCATE]   = "truncate",
24         [TOMOYO_TYPE_SYMLINK]    = "symlink",
25         [TOMOYO_TYPE_REWRITE]    = "rewrite",
26         [TOMOYO_TYPE_CHROOT]     = "chroot",
27         [TOMOYO_TYPE_MOUNT]      = "mount",
28         [TOMOYO_TYPE_UMOUNT]     = "unmount",
29 };
30
31 /* Keyword array for operations with one pathname and three numbers. */
32 static const char *tomoyo_path_number3_keyword
33 [TOMOYO_MAX_PATH_NUMBER3_OPERATION] = {
34         [TOMOYO_TYPE_MKBLOCK]    = "mkblock",
35         [TOMOYO_TYPE_MKCHAR]     = "mkchar",
36 };
37
38 /* Keyword array for operations with two pathnames. */
39 static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
40         [TOMOYO_TYPE_LINK]       = "link",
41         [TOMOYO_TYPE_RENAME]     = "rename",
42         [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
43 };
44
45 /* Keyword array for operations with one pathname and one number. */
46 static const char *tomoyo_path_number_keyword
47 [TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
48         [TOMOYO_TYPE_CREATE]     = "create",
49         [TOMOYO_TYPE_MKDIR]      = "mkdir",
50         [TOMOYO_TYPE_MKFIFO]     = "mkfifo",
51         [TOMOYO_TYPE_MKSOCK]     = "mksock",
52         [TOMOYO_TYPE_IOCTL]      = "ioctl",
53         [TOMOYO_TYPE_CHMOD]      = "chmod",
54         [TOMOYO_TYPE_CHOWN]      = "chown",
55         [TOMOYO_TYPE_CHGRP]      = "chgrp",
56 };
57
58 void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
59 {
60         if (!ptr)
61                 return;
62         if (ptr->is_group)
63                 tomoyo_put_path_group(ptr->group);
64         else
65                 tomoyo_put_name(ptr->filename);
66 }
67
68 bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
69                                const struct tomoyo_name_union *ptr)
70 {
71         if (ptr->is_group)
72                 return tomoyo_path_matches_group(name, ptr->group, 1);
73         return tomoyo_path_matches_pattern(name, ptr->filename);
74 }
75
76 static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info
77                                               *name,
78                                               const struct tomoyo_name_union
79                                               *ptr, const bool may_use_pattern)
80 {
81         if (ptr->is_group)
82                 return tomoyo_path_matches_group(name, ptr->group,
83                                                  may_use_pattern);
84         if (may_use_pattern || !ptr->filename->is_patterned)
85                 return tomoyo_path_matches_pattern(name, ptr->filename);
86         return false;
87 }
88
89 void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
90 {
91         if (ptr && ptr->is_group)
92                 tomoyo_put_number_group(ptr->group);
93 }
94
95 bool tomoyo_compare_number_union(const unsigned long value,
96                                  const struct tomoyo_number_union *ptr)
97 {
98         if (ptr->is_group)
99                 return tomoyo_number_matches_group(value, value, ptr->group);
100         return value >= ptr->values[0] && value <= ptr->values[1];
101 }
102
103 /**
104  * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
105  *
106  * @r:      Pointer to "struct tomoyo_request_info" to initialize.
107  * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
108  *
109  * Returns mode.
110  */
111 static int tomoyo_init_request_info(struct tomoyo_request_info *r,
112                                     struct tomoyo_domain_info *domain)
113 {
114         memset(r, 0, sizeof(*r));
115         if (!domain)
116                 domain = tomoyo_domain();
117         r->domain = domain;
118         r->mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
119         return r->mode;
120 }
121
122 static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
123      __attribute__ ((format(printf, 2, 3)));
124 /**
125  * tomoyo_warn_log - Print warning or error message on console.
126  *
127  * @r:   Pointer to "struct tomoyo_request_info".
128  * @fmt: The printf()'s format string, followed by parameters.
129  */
130 static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
131 {
132         int len = PAGE_SIZE;
133         va_list args;
134         char *buffer;
135         if (!tomoyo_verbose_mode(r->domain))
136                 return;
137         while (1) {
138                 int len2;
139                 buffer = kmalloc(len, GFP_NOFS);
140                 if (!buffer)
141                         return;
142                 va_start(args, fmt);
143                 len2 = vsnprintf(buffer, len - 1, fmt, args);
144                 va_end(args);
145                 if (len2 <= len - 1) {
146                         buffer[len2] = '\0';
147                         break;
148                 }
149                 len = len2 + 1;
150                 kfree(buffer);
151         }
152         printk(KERN_WARNING "TOMOYO-%s: Access %s denied for %s\n",
153                r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING",
154                buffer, tomoyo_get_last_name(r->domain));
155         kfree(buffer);
156 }
157
158 /**
159  * tomoyo_path2keyword - Get the name of single path operation.
160  *
161  * @operation: Type of operation.
162  *
163  * Returns the name of single path operation.
164  */
165 const char *tomoyo_path2keyword(const u8 operation)
166 {
167         return (operation < TOMOYO_MAX_PATH_OPERATION)
168                 ? tomoyo_path_keyword[operation] : NULL;
169 }
170
171 /**
172  * tomoyo_path_number32keyword - Get the name of path/number/number/number operations.
173  *
174  * @operation: Type of operation.
175  *
176  * Returns the name of path/number/number/number operation.
177  */
178 const char *tomoyo_path_number32keyword(const u8 operation)
179 {
180         return (operation < TOMOYO_MAX_PATH_NUMBER3_OPERATION)
181                 ? tomoyo_path_number3_keyword[operation] : NULL;
182 }
183
184 /**
185  * tomoyo_path22keyword - Get the name of double path operation.
186  *
187  * @operation: Type of operation.
188  *
189  * Returns the name of double path operation.
190  */
191 const char *tomoyo_path22keyword(const u8 operation)
192 {
193         return (operation < TOMOYO_MAX_PATH2_OPERATION)
194                 ? tomoyo_path2_keyword[operation] : NULL;
195 }
196
197 /**
198  * tomoyo_path_number2keyword - Get the name of path/number operations.
199  *
200  * @operation: Type of operation.
201  *
202  * Returns the name of path/number operation.
203  */
204 const char *tomoyo_path_number2keyword(const u8 operation)
205 {
206         return (operation < TOMOYO_MAX_PATH_NUMBER_OPERATION)
207                 ? tomoyo_path_number_keyword[operation] : NULL;
208 }
209
210 /**
211  * tomoyo_strendswith - Check whether the token ends with the given token.
212  *
213  * @name: The token to check.
214  * @tail: The token to find.
215  *
216  * Returns true if @name ends with @tail, false otherwise.
217  */
218 static bool tomoyo_strendswith(const char *name, const char *tail)
219 {
220         int len;
221
222         if (!name || !tail)
223                 return false;
224         len = strlen(name) - strlen(tail);
225         return len >= 0 && !strcmp(name + len, tail);
226 }
227
228 /**
229  * tomoyo_get_path - Get realpath.
230  *
231  * @path: Pointer to "struct path".
232  *
233  * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
234  */
235 static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
236 {
237         int error;
238         struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf),
239                                                          GFP_NOFS);
240
241         if (!buf)
242                 return NULL;
243         /* Reserve one byte for appending "/". */
244         error = tomoyo_realpath_from_path2(path, buf->body,
245                                            sizeof(buf->body) - 2);
246         if (!error) {
247                 buf->head.name = buf->body;
248                 tomoyo_fill_path_info(&buf->head);
249                 return &buf->head;
250         }
251         kfree(buf);
252         return NULL;
253 }
254
255 static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
256                                    const char *filename2,
257                                    struct tomoyo_domain_info *const domain,
258                                    const bool is_delete);
259 static int tomoyo_update_path_acl(const u8 type, const char *filename,
260                                   struct tomoyo_domain_info *const domain,
261                                   const bool is_delete);
262
263 /*
264  * tomoyo_globally_readable_list is used for holding list of pathnames which
265  * are by default allowed to be open()ed for reading by any process.
266  *
267  * An entry is added by
268  *
269  * # echo 'allow_read /lib/libc-2.5.so' > \
270  *                               /sys/kernel/security/tomoyo/exception_policy
271  *
272  * and is deleted by
273  *
274  * # echo 'delete allow_read /lib/libc-2.5.so' > \
275  *                               /sys/kernel/security/tomoyo/exception_policy
276  *
277  * and all entries are retrieved by
278  *
279  * # grep ^allow_read /sys/kernel/security/tomoyo/exception_policy
280  *
281  * In the example above, any process is allowed to
282  * open("/lib/libc-2.5.so", O_RDONLY).
283  * One exception is, if the domain which current process belongs to is marked
284  * as "ignore_global_allow_read", current process can't do so unless explicitly
285  * given "allow_read /lib/libc-2.5.so" to the domain which current process
286  * belongs to.
287  */
288 LIST_HEAD(tomoyo_globally_readable_list);
289
290 /**
291  * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list.
292  *
293  * @filename:  Filename unconditionally permitted to open() for reading.
294  * @is_delete: True if it is a delete request.
295  *
296  * Returns 0 on success, negative value otherwise.
297  *
298  * Caller holds tomoyo_read_lock().
299  */
300 static int tomoyo_update_globally_readable_entry(const char *filename,
301                                                  const bool is_delete)
302 {
303         struct tomoyo_globally_readable_file_entry *ptr;
304         struct tomoyo_globally_readable_file_entry e = { };
305         int error = is_delete ? -ENOENT : -ENOMEM;
306
307         if (!tomoyo_is_correct_path(filename, 1, 0, -1))
308                 return -EINVAL;
309         e.filename = tomoyo_get_name(filename);
310         if (!e.filename)
311                 return -ENOMEM;
312         if (mutex_lock_interruptible(&tomoyo_policy_lock))
313                 goto out;
314         list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
315                 if (ptr->filename != e.filename)
316                         continue;
317                 ptr->is_deleted = is_delete;
318                 error = 0;
319                 break;
320         }
321         if (!is_delete && error) {
322                 struct tomoyo_globally_readable_file_entry *entry =
323                         tomoyo_commit_ok(&e, sizeof(e));
324                 if (entry) {
325                         list_add_tail_rcu(&entry->list,
326                                           &tomoyo_globally_readable_list);
327                         error = 0;
328                 }
329         }
330         mutex_unlock(&tomoyo_policy_lock);
331  out:
332         tomoyo_put_name(e.filename);
333         return error;
334 }
335
336 /**
337  * tomoyo_is_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
338  *
339  * @filename: The filename to check.
340  *
341  * Returns true if any domain can open @filename for reading, false otherwise.
342  *
343  * Caller holds tomoyo_read_lock().
344  */
345 static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
346                                              filename)
347 {
348         struct tomoyo_globally_readable_file_entry *ptr;
349         bool found = false;
350
351         list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
352                 if (!ptr->is_deleted &&
353                     tomoyo_path_matches_pattern(filename, ptr->filename)) {
354                         found = true;
355                         break;
356                 }
357         }
358         return found;
359 }
360
361 /**
362  * tomoyo_write_globally_readable_policy - Write "struct tomoyo_globally_readable_file_entry" list.
363  *
364  * @data:      String to parse.
365  * @is_delete: True if it is a delete request.
366  *
367  * Returns 0 on success, negative value otherwise.
368  *
369  * Caller holds tomoyo_read_lock().
370  */
371 int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
372 {
373         return tomoyo_update_globally_readable_entry(data, is_delete);
374 }
375
376 /**
377  * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list.
378  *
379  * @head: Pointer to "struct tomoyo_io_buffer".
380  *
381  * Returns true on success, false otherwise.
382  *
383  * Caller holds tomoyo_read_lock().
384  */
385 bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
386 {
387         struct list_head *pos;
388         bool done = true;
389
390         list_for_each_cookie(pos, head->read_var2,
391                              &tomoyo_globally_readable_list) {
392                 struct tomoyo_globally_readable_file_entry *ptr;
393                 ptr = list_entry(pos,
394                                  struct tomoyo_globally_readable_file_entry,
395                                  list);
396                 if (ptr->is_deleted)
397                         continue;
398                 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n",
399                                         ptr->filename->name);
400                 if (!done)
401                         break;
402         }
403         return done;
404 }
405
406 /* tomoyo_pattern_list is used for holding list of pathnames which are used for
407  * converting pathnames to pathname patterns during learning mode.
408  *
409  * An entry is added by
410  *
411  * # echo 'file_pattern /proc/\$/mounts' > \
412  *                             /sys/kernel/security/tomoyo/exception_policy
413  *
414  * and is deleted by
415  *
416  * # echo 'delete file_pattern /proc/\$/mounts' > \
417  *                             /sys/kernel/security/tomoyo/exception_policy
418  *
419  * and all entries are retrieved by
420  *
421  * # grep ^file_pattern /sys/kernel/security/tomoyo/exception_policy
422  *
423  * In the example above, if a process which belongs to a domain which is in
424  * learning mode requested open("/proc/1/mounts", O_RDONLY),
425  * "allow_read /proc/\$/mounts" is automatically added to the domain which that
426  * process belongs to.
427  *
428  * It is not a desirable behavior that we have to use /proc/\$/ instead of
429  * /proc/self/ when current process needs to access only current process's
430  * information. As of now, LSM version of TOMOYO is using __d_path() for
431  * calculating pathname. Non LSM version of TOMOYO is using its own function
432  * which pretends as if /proc/self/ is not a symlink; so that we can forbid
433  * current process from accessing other process's information.
434  */
435 LIST_HEAD(tomoyo_pattern_list);
436
437 /**
438  * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
439  *
440  * @pattern:   Pathname pattern.
441  * @is_delete: True if it is a delete request.
442  *
443  * Returns 0 on success, negative value otherwise.
444  *
445  * Caller holds tomoyo_read_lock().
446  */
447 static int tomoyo_update_file_pattern_entry(const char *pattern,
448                                             const bool is_delete)
449 {
450         struct tomoyo_pattern_entry *ptr;
451         struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
452         int error = is_delete ? -ENOENT : -ENOMEM;
453
454         if (!e.pattern)
455                 return error;
456         if (!e.pattern->is_patterned)
457                 goto out;
458         if (mutex_lock_interruptible(&tomoyo_policy_lock))
459                 goto out;
460         list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
461                 if (e.pattern != ptr->pattern)
462                         continue;
463                 ptr->is_deleted = is_delete;
464                 error = 0;
465                 break;
466         }
467         if (!is_delete && error) {
468                 struct tomoyo_pattern_entry *entry =
469                         tomoyo_commit_ok(&e, sizeof(e));
470                 if (entry) {
471                         list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
472                         error = 0;
473                 }
474         }
475         mutex_unlock(&tomoyo_policy_lock);
476  out:
477         tomoyo_put_name(e.pattern);
478         return error;
479 }
480
481 /**
482  * tomoyo_get_file_pattern - Get patterned pathname.
483  *
484  * @filename: The filename to find patterned pathname.
485  *
486  * Returns pointer to pathname pattern if matched, @filename otherwise.
487  *
488  * Caller holds tomoyo_read_lock().
489  */
490 static const struct tomoyo_path_info *
491 tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
492 {
493         struct tomoyo_pattern_entry *ptr;
494         const struct tomoyo_path_info *pattern = NULL;
495
496         list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
497                 if (ptr->is_deleted)
498                         continue;
499                 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
500                         continue;
501                 pattern = ptr->pattern;
502                 if (tomoyo_strendswith(pattern->name, "/\\*")) {
503                         /* Do nothing. Try to find the better match. */
504                 } else {
505                         /* This would be the better match. Use this. */
506                         break;
507                 }
508         }
509         if (pattern)
510                 filename = pattern;
511         return filename;
512 }
513
514 /**
515  * tomoyo_write_pattern_policy - Write "struct tomoyo_pattern_entry" list.
516  *
517  * @data:      String to parse.
518  * @is_delete: True if it is a delete request.
519  *
520  * Returns 0 on success, negative value otherwise.
521  *
522  * Caller holds tomoyo_read_lock().
523  */
524 int tomoyo_write_pattern_policy(char *data, const bool is_delete)
525 {
526         return tomoyo_update_file_pattern_entry(data, is_delete);
527 }
528
529 /**
530  * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list.
531  *
532  * @head: Pointer to "struct tomoyo_io_buffer".
533  *
534  * Returns true on success, false otherwise.
535  *
536  * Caller holds tomoyo_read_lock().
537  */
538 bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
539 {
540         struct list_head *pos;
541         bool done = true;
542
543         list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
544                 struct tomoyo_pattern_entry *ptr;
545                 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
546                 if (ptr->is_deleted)
547                         continue;
548                 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN
549                                         "%s\n", ptr->pattern->name);
550                 if (!done)
551                         break;
552         }
553         return done;
554 }
555
556 /*
557  * tomoyo_no_rewrite_list is used for holding list of pathnames which are by
558  * default forbidden to modify already written content of a file.
559  *
560  * An entry is added by
561  *
562  * # echo 'deny_rewrite /var/log/messages' > \
563  *                              /sys/kernel/security/tomoyo/exception_policy
564  *
565  * and is deleted by
566  *
567  * # echo 'delete deny_rewrite /var/log/messages' > \
568  *                              /sys/kernel/security/tomoyo/exception_policy
569  *
570  * and all entries are retrieved by
571  *
572  * # grep ^deny_rewrite /sys/kernel/security/tomoyo/exception_policy
573  *
574  * In the example above, if a process requested to rewrite /var/log/messages ,
575  * the process can't rewrite unless the domain which that process belongs to
576  * has "allow_rewrite /var/log/messages" entry.
577  *
578  * It is not a desirable behavior that we have to add "\040(deleted)" suffix
579  * when we want to allow rewriting already unlink()ed file. As of now,
580  * LSM version of TOMOYO is using __d_path() for calculating pathname.
581  * Non LSM version of TOMOYO is using its own function which doesn't append
582  * " (deleted)" suffix if the file is already unlink()ed; so that we don't
583  * need to worry whether the file is already unlink()ed or not.
584  */
585 LIST_HEAD(tomoyo_no_rewrite_list);
586
587 /**
588  * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list.
589  *
590  * @pattern:   Pathname pattern that are not rewritable by default.
591  * @is_delete: True if it is a delete request.
592  *
593  * Returns 0 on success, negative value otherwise.
594  *
595  * Caller holds tomoyo_read_lock().
596  */
597 static int tomoyo_update_no_rewrite_entry(const char *pattern,
598                                           const bool is_delete)
599 {
600         struct tomoyo_no_rewrite_entry *ptr;
601         struct tomoyo_no_rewrite_entry e = { };
602         int error = is_delete ? -ENOENT : -ENOMEM;
603
604         if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
605                 return -EINVAL;
606         e.pattern = tomoyo_get_name(pattern);
607         if (!e.pattern)
608                 return error;
609         if (mutex_lock_interruptible(&tomoyo_policy_lock))
610                 goto out;
611         list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
612                 if (ptr->pattern != e.pattern)
613                         continue;
614                 ptr->is_deleted = is_delete;
615                 error = 0;
616                 break;
617         }
618         if (!is_delete && error) {
619                 struct tomoyo_no_rewrite_entry *entry =
620                         tomoyo_commit_ok(&e, sizeof(e));
621                 if (entry) {
622                         list_add_tail_rcu(&entry->list,
623                                           &tomoyo_no_rewrite_list);
624                         error = 0;
625                 }
626         }
627         mutex_unlock(&tomoyo_policy_lock);
628  out:
629         tomoyo_put_name(e.pattern);
630         return error;
631 }
632
633 /**
634  * tomoyo_is_no_rewrite_file - Check if the given pathname is not permitted to be rewrited.
635  *
636  * @filename: Filename to check.
637  *
638  * Returns true if @filename is specified by "deny_rewrite" directive,
639  * false otherwise.
640  *
641  * Caller holds tomoyo_read_lock().
642  */
643 static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
644 {
645         struct tomoyo_no_rewrite_entry *ptr;
646         bool found = false;
647
648         list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
649                 if (ptr->is_deleted)
650                         continue;
651                 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
652                         continue;
653                 found = true;
654                 break;
655         }
656         return found;
657 }
658
659 /**
660  * tomoyo_write_no_rewrite_policy - Write "struct tomoyo_no_rewrite_entry" list.
661  *
662  * @data:      String to parse.
663  * @is_delete: True if it is a delete request.
664  *
665  * Returns 0 on success, negative value otherwise.
666  *
667  * Caller holds tomoyo_read_lock().
668  */
669 int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
670 {
671         return tomoyo_update_no_rewrite_entry(data, is_delete);
672 }
673
674 /**
675  * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list.
676  *
677  * @head: Pointer to "struct tomoyo_io_buffer".
678  *
679  * Returns true on success, false otherwise.
680  *
681  * Caller holds tomoyo_read_lock().
682  */
683 bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
684 {
685         struct list_head *pos;
686         bool done = true;
687
688         list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
689                 struct tomoyo_no_rewrite_entry *ptr;
690                 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
691                 if (ptr->is_deleted)
692                         continue;
693                 done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE
694                                         "%s\n", ptr->pattern->name);
695                 if (!done)
696                         break;
697         }
698         return done;
699 }
700
701 /**
702  * tomoyo_update_file_acl - Update file's read/write/execute ACL.
703  *
704  * @perm:      Permission (between 1 to 7).
705  * @filename:  Filename.
706  * @domain:    Pointer to "struct tomoyo_domain_info".
707  * @is_delete: True if it is a delete request.
708  *
709  * Returns 0 on success, negative value otherwise.
710  *
711  * This is legacy support interface for older policy syntax.
712  * Current policy syntax uses "allow_read/write" instead of "6",
713  * "allow_read" instead of "4", "allow_write" instead of "2",
714  * "allow_execute" instead of "1".
715  *
716  * Caller holds tomoyo_read_lock().
717  */
718 static int tomoyo_update_file_acl(u8 perm, const char *filename,
719                                   struct tomoyo_domain_info * const domain,
720                                   const bool is_delete)
721 {
722         if (perm > 7 || !perm) {
723                 printk(KERN_DEBUG "%s: Invalid permission '%d %s'\n",
724                        __func__, perm, filename);
725                 return -EINVAL;
726         }
727         if (filename[0] != '@' && tomoyo_strendswith(filename, "/"))
728                 /*
729                  * Only 'allow_mkdir' and 'allow_rmdir' are valid for
730                  * directory permissions.
731                  */
732                 return 0;
733         if (perm & 4)
734                 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain,
735                                        is_delete);
736         if (perm & 2)
737                 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain,
738                                        is_delete);
739         if (perm & 1)
740                 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain,
741                                        is_delete);
742         return 0;
743 }
744
745 /**
746  * tomoyo_path_acl - Check permission for single path operation.
747  *
748  * @r:               Pointer to "struct tomoyo_request_info".
749  * @filename:        Filename to check.
750  * @perm:            Permission.
751  * @may_use_pattern: True if patterned ACL is permitted.
752  *
753  * Returns 0 on success, -EPERM otherwise.
754  *
755  * Caller holds tomoyo_read_lock().
756  */
757 static int tomoyo_path_acl(const struct tomoyo_request_info *r,
758                            const struct tomoyo_path_info *filename,
759                            const u32 perm, const bool may_use_pattern)
760 {
761         struct tomoyo_domain_info *domain = r->domain;
762         struct tomoyo_acl_info *ptr;
763         int error = -EPERM;
764
765         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
766                 struct tomoyo_path_acl *acl;
767                 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
768                         continue;
769                 acl = container_of(ptr, struct tomoyo_path_acl, head);
770                 if (!(acl->perm & perm) ||
771                     !tomoyo_compare_name_union_pattern(filename, &acl->name,
772                                                        may_use_pattern))
773                         continue;
774                 error = 0;
775                 break;
776         }
777         return error;
778 }
779
780 /**
781  * tomoyo_file_perm - Check permission for opening files.
782  *
783  * @r:         Pointer to "struct tomoyo_request_info".
784  * @filename:  Filename to check.
785  * @mode:      Mode ("read" or "write" or "read/write" or "execute").
786  *
787  * Returns 0 on success, negative value otherwise.
788  *
789  * Caller holds tomoyo_read_lock().
790  */
791 static int tomoyo_file_perm(struct tomoyo_request_info *r,
792                             const struct tomoyo_path_info *filename,
793                             const u8 mode)
794 {
795         const char *msg = "<unknown>";
796         int error = 0;
797         u32 perm = 0;
798
799         if (!filename)
800                 return 0;
801
802         if (mode == 6) {
803                 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
804                 perm = 1 << TOMOYO_TYPE_READ_WRITE;
805         } else if (mode == 4) {
806                 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
807                 perm = 1 << TOMOYO_TYPE_READ;
808         } else if (mode == 2) {
809                 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
810                 perm = 1 << TOMOYO_TYPE_WRITE;
811         } else if (mode == 1) {
812                 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
813                 perm = 1 << TOMOYO_TYPE_EXECUTE;
814         } else
815                 BUG();
816         error = tomoyo_path_acl(r, filename, perm, mode != 1);
817         if (error && mode == 4 && !r->domain->ignore_global_allow_read
818             && tomoyo_is_globally_readable_file(filename))
819                 error = 0;
820         if (!error)
821                 return 0;
822         tomoyo_warn_log(r, "%s %s", msg, filename->name);
823         if (r->mode == TOMOYO_CONFIG_ENFORCING)
824                 return error;
825         if (tomoyo_domain_quota_is_ok(r)) {
826                 /* Don't use patterns for execute permission. */
827                 const struct tomoyo_path_info *patterned_file = (mode != 1) ?
828                         tomoyo_get_file_pattern(filename) : filename;
829                 tomoyo_update_file_acl(mode, patterned_file->name, r->domain,
830                                        false);
831         }
832         return 0;
833 }
834
835 /**
836  * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
837  *
838  * @type:      Type of operation.
839  * @filename:  Filename.
840  * @domain:    Pointer to "struct tomoyo_domain_info".
841  * @is_delete: True if it is a delete request.
842  *
843  * Returns 0 on success, negative value otherwise.
844  *
845  * Caller holds tomoyo_read_lock().
846  */
847 static int tomoyo_update_path_acl(const u8 type, const char *filename,
848                                   struct tomoyo_domain_info *const domain,
849                                   const bool is_delete)
850 {
851         static const u16 tomoyo_rw_mask =
852                 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
853         const u16 perm = 1 << type;
854         struct tomoyo_acl_info *ptr;
855         struct tomoyo_path_acl e = {
856                 .head.type = TOMOYO_TYPE_PATH_ACL,
857                 .perm = perm
858         };
859         int error = is_delete ? -ENOENT : -ENOMEM;
860
861         if (type == TOMOYO_TYPE_READ_WRITE)
862                 e.perm |= tomoyo_rw_mask;
863         if (!domain)
864                 return -EINVAL;
865         if (!tomoyo_parse_name_union(filename, &e.name))
866                 return -EINVAL;
867         if (mutex_lock_interruptible(&tomoyo_policy_lock))
868                 goto out;
869         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
870                 struct tomoyo_path_acl *acl =
871                         container_of(ptr, struct tomoyo_path_acl, head);
872                 if (!tomoyo_is_same_path_acl(acl, &e))
873                         continue;
874                 if (is_delete) {
875                         acl->perm &= ~perm;
876                         if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask)
877                                 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
878                         else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
879                                 acl->perm &= ~tomoyo_rw_mask;
880                 } else {
881                         acl->perm |= perm;
882                         if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask)
883                                 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
884                         else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
885                                 acl->perm |= tomoyo_rw_mask;
886                 }
887                 error = 0;
888                 break;
889         }
890         if (!is_delete && error) {
891                 struct tomoyo_path_acl *entry =
892                         tomoyo_commit_ok(&e, sizeof(e));
893                 if (entry) {
894                         list_add_tail_rcu(&entry->head.list,
895                                           &domain->acl_info_list);
896                         error = 0;
897                 }
898         }
899         mutex_unlock(&tomoyo_policy_lock);
900  out:
901         tomoyo_put_name_union(&e.name);
902         return error;
903 }
904
905 /**
906  * tomoyo_update_path_number3_acl - Update "struct tomoyo_path_number3_acl" list.
907  *
908  * @type:      Type of operation.
909  * @filename:  Filename.
910  * @mode:      Create mode.
911  * @major:     Device major number.
912  * @minor:     Device minor number.
913  * @domain:    Pointer to "struct tomoyo_domain_info".
914  * @is_delete: True if it is a delete request.
915  *
916  * Returns 0 on success, negative value otherwise.
917  */
918 static inline int tomoyo_update_path_number3_acl(const u8 type,
919                                                  const char *filename,
920                                                  char *mode,
921                                                  char *major, char *minor,
922                                                  struct tomoyo_domain_info *
923                                                  const domain,
924                                                  const bool is_delete)
925 {
926         const u8 perm = 1 << type;
927         struct tomoyo_acl_info *ptr;
928         struct tomoyo_path_number3_acl e = {
929                 .head.type = TOMOYO_TYPE_PATH_NUMBER3_ACL,
930                 .perm = perm
931         };
932         int error = is_delete ? -ENOENT : -ENOMEM;
933         if (!tomoyo_parse_name_union(filename, &e.name) ||
934             !tomoyo_parse_number_union(mode, &e.mode) ||
935             !tomoyo_parse_number_union(major, &e.major) ||
936             !tomoyo_parse_number_union(minor, &e.minor))
937                 goto out;
938         if (mutex_lock_interruptible(&tomoyo_policy_lock))
939                 goto out;
940         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
941                 struct tomoyo_path_number3_acl *acl =
942                         container_of(ptr, struct tomoyo_path_number3_acl, head);
943                 if (!tomoyo_is_same_path_number3_acl(acl, &e))
944                         continue;
945                 if (is_delete)
946                         acl->perm &= ~perm;
947                 else
948                         acl->perm |= perm;
949                 error = 0;
950                 break;
951         }
952         if (!is_delete && error) {
953                 struct tomoyo_path_number3_acl *entry =
954                         tomoyo_commit_ok(&e, sizeof(e));
955                 if (entry) {
956                         list_add_tail_rcu(&entry->head.list,
957                                           &domain->acl_info_list);
958                         error = 0;
959                 }
960         }
961         mutex_unlock(&tomoyo_policy_lock);
962  out:
963         tomoyo_put_name_union(&e.name);
964         tomoyo_put_number_union(&e.mode);
965         tomoyo_put_number_union(&e.major);
966         tomoyo_put_number_union(&e.minor);
967         return error;
968 }
969
970 /**
971  * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
972  *
973  * @type:      Type of operation.
974  * @filename1: First filename.
975  * @filename2: Second filename.
976  * @domain:    Pointer to "struct tomoyo_domain_info".
977  * @is_delete: True if it is a delete request.
978  *
979  * Returns 0 on success, negative value otherwise.
980  *
981  * Caller holds tomoyo_read_lock().
982  */
983 static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
984                                    const char *filename2,
985                                    struct tomoyo_domain_info *const domain,
986                                    const bool is_delete)
987 {
988         const u8 perm = 1 << type;
989         struct tomoyo_path2_acl e = {
990                 .head.type = TOMOYO_TYPE_PATH2_ACL,
991                 .perm = perm
992         };
993         struct tomoyo_acl_info *ptr;
994         int error = is_delete ? -ENOENT : -ENOMEM;
995
996         if (!domain)
997                 return -EINVAL;
998         if (!tomoyo_parse_name_union(filename1, &e.name1) ||
999             !tomoyo_parse_name_union(filename2, &e.name2))
1000                 goto out;
1001         if (mutex_lock_interruptible(&tomoyo_policy_lock))
1002                 goto out;
1003         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1004                 struct tomoyo_path2_acl *acl =
1005                         container_of(ptr, struct tomoyo_path2_acl, head);
1006                 if (!tomoyo_is_same_path2_acl(acl, &e))
1007                         continue;
1008                 if (is_delete)
1009                         acl->perm &= ~perm;
1010                 else
1011                         acl->perm |= perm;
1012                 error = 0;
1013                 break;
1014         }
1015         if (!is_delete && error) {
1016                 struct tomoyo_path2_acl *entry =
1017                         tomoyo_commit_ok(&e, sizeof(e));
1018                 if (entry) {
1019                         list_add_tail_rcu(&entry->head.list,
1020                                           &domain->acl_info_list);
1021                         error = 0;
1022                 }
1023         }
1024         mutex_unlock(&tomoyo_policy_lock);
1025  out:
1026         tomoyo_put_name_union(&e.name1);
1027         tomoyo_put_name_union(&e.name2);
1028         return error;
1029 }
1030
1031 /**
1032  * tomoyo_path_number3_acl - Check permission for path/number/number/number operation.
1033  *
1034  * @r:        Pointer to "struct tomoyo_request_info".
1035  * @filename: Filename to check.
1036  * @perm:     Permission.
1037  * @mode:     Create mode.
1038  * @major:    Device major number.
1039  * @minor:    Device minor number.
1040  *
1041  * Returns 0 on success, -EPERM otherwise.
1042  *
1043  * Caller holds tomoyo_read_lock().
1044  */
1045 static int tomoyo_path_number3_acl(struct tomoyo_request_info *r,
1046                                    const struct tomoyo_path_info *filename,
1047                                    const u16 perm, const unsigned int mode,
1048                                    const unsigned int major,
1049                                    const unsigned int minor)
1050 {
1051         struct tomoyo_domain_info *domain = r->domain;
1052         struct tomoyo_acl_info *ptr;
1053         int error = -EPERM;
1054         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1055                 struct tomoyo_path_number3_acl *acl;
1056                 if (ptr->type != TOMOYO_TYPE_PATH_NUMBER3_ACL)
1057                         continue;
1058                 acl = container_of(ptr, struct tomoyo_path_number3_acl, head);
1059                 if (!tomoyo_compare_number_union(mode, &acl->mode))
1060                         continue;
1061                 if (!tomoyo_compare_number_union(major, &acl->major))
1062                         continue;
1063                 if (!tomoyo_compare_number_union(minor, &acl->minor))
1064                         continue;
1065                 if (!(acl->perm & perm))
1066                         continue;
1067                 if (!tomoyo_compare_name_union(filename, &acl->name))
1068                         continue;
1069                 error = 0;
1070                 break;
1071         }
1072         return error;
1073 }
1074
1075 /**
1076  * tomoyo_path2_acl - Check permission for double path operation.
1077  *
1078  * @r:         Pointer to "struct tomoyo_request_info".
1079  * @type:      Type of operation.
1080  * @filename1: First filename to check.
1081  * @filename2: Second filename to check.
1082  *
1083  * Returns 0 on success, -EPERM otherwise.
1084  *
1085  * Caller holds tomoyo_read_lock().
1086  */
1087 static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type,
1088                             const struct tomoyo_path_info *filename1,
1089                             const struct tomoyo_path_info *filename2)
1090 {
1091         const struct tomoyo_domain_info *domain = r->domain;
1092         struct tomoyo_acl_info *ptr;
1093         const u8 perm = 1 << type;
1094         int error = -EPERM;
1095
1096         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1097                 struct tomoyo_path2_acl *acl;
1098                 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
1099                         continue;
1100                 acl = container_of(ptr, struct tomoyo_path2_acl, head);
1101                 if (!(acl->perm & perm))
1102                         continue;
1103                 if (!tomoyo_compare_name_union(filename1, &acl->name1))
1104                         continue;
1105                 if (!tomoyo_compare_name_union(filename2, &acl->name2))
1106                         continue;
1107                 error = 0;
1108                 break;
1109         }
1110         return error;
1111 }
1112
1113 /**
1114  * tomoyo_path_permission - Check permission for single path operation.
1115  *
1116  * @r:         Pointer to "struct tomoyo_request_info".
1117  * @operation: Type of operation.
1118  * @filename:  Filename to check.
1119  *
1120  * Returns 0 on success, negative value otherwise.
1121  *
1122  * Caller holds tomoyo_read_lock().
1123  */
1124 static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
1125                                   const struct tomoyo_path_info *filename)
1126 {
1127         int error;
1128
1129  next:
1130         error = tomoyo_path_acl(r, filename, 1 << operation, 1);
1131         if (!error)
1132                 goto ok;
1133         tomoyo_warn_log(r, "%s %s", tomoyo_path2keyword(operation),
1134                         filename->name);
1135         if (tomoyo_domain_quota_is_ok(r)) {
1136                 const char *name = tomoyo_get_file_pattern(filename)->name;
1137                 tomoyo_update_path_acl(operation, name, r->domain, false);
1138         }
1139         if (r->mode != TOMOYO_CONFIG_ENFORCING)
1140                 error = 0;
1141  ok:
1142         /*
1143          * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
1144          * we need to check "allow_rewrite" permission if the filename is
1145          * specified by "deny_rewrite" keyword.
1146          */
1147         if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
1148             tomoyo_is_no_rewrite_file(filename)) {
1149                 operation = TOMOYO_TYPE_REWRITE;
1150                 goto next;
1151         }
1152         return error;
1153 }
1154
1155 /**
1156  * tomoyo_path_number_acl - Check permission for ioctl/chmod/chown/chgrp operation.
1157  *
1158  * @r:        Pointer to "struct tomoyo_request_info".
1159  * @type:     Operation.
1160  * @filename: Filename to check.
1161  * @number:   Number.
1162  *
1163  * Returns 0 on success, -EPERM otherwise.
1164  *
1165  * Caller holds tomoyo_read_lock().
1166  */
1167 static int tomoyo_path_number_acl(struct tomoyo_request_info *r, const u8 type,
1168                                   const struct tomoyo_path_info *filename,
1169                                   const unsigned long number)
1170 {
1171         struct tomoyo_domain_info *domain = r->domain;
1172         struct tomoyo_acl_info *ptr;
1173         const u8 perm = 1 << type;
1174         int error = -EPERM;
1175         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1176                 struct tomoyo_path_number_acl *acl;
1177                 if (ptr->type != TOMOYO_TYPE_PATH_NUMBER_ACL)
1178                         continue;
1179                 acl = container_of(ptr, struct tomoyo_path_number_acl,
1180                                    head);
1181                 if (!(acl->perm & perm) ||
1182                     !tomoyo_compare_number_union(number, &acl->number) ||
1183                     !tomoyo_compare_name_union(filename, &acl->name))
1184                         continue;
1185                 error = 0;
1186                 break;
1187         }
1188         return error;
1189 }
1190
1191 /**
1192  * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
1193  *
1194  * @type:      Type of operation.
1195  * @filename:  Filename.
1196  * @number:    Number.
1197  * @domain:    Pointer to "struct tomoyo_domain_info".
1198  * @is_delete: True if it is a delete request.
1199  *
1200  * Returns 0 on success, negative value otherwise.
1201  */
1202 static inline int tomoyo_update_path_number_acl(const u8 type,
1203                                                 const char *filename,
1204                                                 char *number,
1205                                                 struct tomoyo_domain_info *
1206                                                 const domain,
1207                                                 const bool is_delete)
1208 {
1209         const u8 perm = 1 << type;
1210         struct tomoyo_acl_info *ptr;
1211         struct tomoyo_path_number_acl e = {
1212                 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
1213                 .perm = perm
1214         };
1215         int error = is_delete ? -ENOENT : -ENOMEM;
1216         if (!domain)
1217                 return -EINVAL;
1218         if (!tomoyo_parse_name_union(filename, &e.name))
1219                 return -EINVAL;
1220         if (!tomoyo_parse_number_union(number, &e.number))
1221                 goto out;
1222         if (mutex_lock_interruptible(&tomoyo_policy_lock))
1223                 goto out;
1224         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1225                 struct tomoyo_path_number_acl *acl =
1226                         container_of(ptr, struct tomoyo_path_number_acl, head);
1227                 if (!tomoyo_is_same_path_number_acl(acl, &e))
1228                         continue;
1229                 if (is_delete)
1230                         acl->perm &= ~perm;
1231                 else
1232                         acl->perm |= perm;
1233                 error = 0;
1234                 break;
1235         }
1236         if (!is_delete && error) {
1237                 struct tomoyo_path_number_acl *entry =
1238                         tomoyo_commit_ok(&e, sizeof(e));
1239                 if (entry) {
1240                         list_add_tail_rcu(&entry->head.list,
1241                                           &domain->acl_info_list);
1242                         error = 0;
1243                 }
1244         }
1245         mutex_unlock(&tomoyo_policy_lock);
1246  out:
1247         tomoyo_put_name_union(&e.name);
1248         tomoyo_put_number_union(&e.number);
1249         return error;
1250 }
1251
1252 /**
1253  * tomoyo_path_number_perm2 - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
1254  *
1255  * @r:        Pointer to "strct tomoyo_request_info".
1256  * @filename: Filename to check.
1257  * @number:   Number.
1258  *
1259  * Returns 0 on success, negative value otherwise.
1260  *
1261  * Caller holds tomoyo_read_lock().
1262  */
1263 static int tomoyo_path_number_perm2(struct tomoyo_request_info *r,
1264                                     const u8 type,
1265                                     const struct tomoyo_path_info *filename,
1266                                     const unsigned long number)
1267 {
1268         char buffer[64];
1269         int error;
1270         u8 radix;
1271
1272         if (!filename)
1273                 return 0;
1274         switch (type) {
1275         case TOMOYO_TYPE_CREATE:
1276         case TOMOYO_TYPE_MKDIR:
1277         case TOMOYO_TYPE_MKFIFO:
1278         case TOMOYO_TYPE_MKSOCK:
1279         case TOMOYO_TYPE_CHMOD:
1280                 radix = TOMOYO_VALUE_TYPE_OCTAL;
1281                 break;
1282         case TOMOYO_TYPE_IOCTL:
1283                 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
1284                 break;
1285         default:
1286                 radix = TOMOYO_VALUE_TYPE_DECIMAL;
1287                 break;
1288         }
1289         tomoyo_print_ulong(buffer, sizeof(buffer), number, radix);
1290         error = tomoyo_path_number_acl(r, type, filename, number);
1291         if (!error)
1292                 return 0;
1293         tomoyo_warn_log(r, "%s %s %s", tomoyo_path_number2keyword(type),
1294                         filename->name, buffer);
1295         if (tomoyo_domain_quota_is_ok(r))
1296                 tomoyo_update_path_number_acl(type,
1297                                               tomoyo_get_file_pattern(filename)
1298                                               ->name, buffer, r->domain, false);
1299         if (r->mode != TOMOYO_CONFIG_ENFORCING)
1300                 error = 0;
1301         return error;
1302 }
1303
1304 /**
1305  * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
1306  *
1307  * @type:   Type of operation.
1308  * @path:   Pointer to "struct path".
1309  * @number: Number.
1310  *
1311  * Returns 0 on success, negative value otherwise.
1312  */
1313 int tomoyo_path_number_perm(const u8 type, struct path *path,
1314                             unsigned long number)
1315 {
1316         struct tomoyo_request_info r;
1317         int error = -ENOMEM;
1318         struct tomoyo_path_info *buf;
1319         int idx;
1320
1321         if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1322             !path->mnt || !path->dentry)
1323                 return 0;
1324         idx = tomoyo_read_lock();
1325         buf = tomoyo_get_path(path);
1326         if (!buf)
1327                 goto out;
1328         if (type == TOMOYO_TYPE_MKDIR && !buf->is_dir) {
1329                 /*
1330                  * tomoyo_get_path() reserves space for appending "/."
1331                  */
1332                 strcat((char *) buf->name, "/");
1333                 tomoyo_fill_path_info(buf);
1334         }
1335         error = tomoyo_path_number_perm2(&r, type, buf, number);
1336  out:
1337         kfree(buf);
1338         tomoyo_read_unlock(idx);
1339         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1340                 error = 0;
1341         return error;
1342 }
1343
1344 /**
1345  * tomoyo_check_exec_perm - Check permission for "execute".
1346  *
1347  * @domain:   Pointer to "struct tomoyo_domain_info".
1348  * @filename: Check permission for "execute".
1349  *
1350  * Returns 0 on success, negativevalue otherwise.
1351  *
1352  * Caller holds tomoyo_read_lock().
1353  */
1354 int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1355                            const struct tomoyo_path_info *filename)
1356 {
1357         struct tomoyo_request_info r;
1358
1359         if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED)
1360                 return 0;
1361         return tomoyo_file_perm(&r, filename, 1);
1362 }
1363
1364 /**
1365  * tomoyo_check_open_permission - Check permission for "read" and "write".
1366  *
1367  * @domain: Pointer to "struct tomoyo_domain_info".
1368  * @path:   Pointer to "struct path".
1369  * @flag:   Flags for open().
1370  *
1371  * Returns 0 on success, negative value otherwise.
1372  */
1373 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1374                                  struct path *path, const int flag)
1375 {
1376         const u8 acc_mode = ACC_MODE(flag);
1377         int error = -ENOMEM;
1378         struct tomoyo_path_info *buf;
1379         struct tomoyo_request_info r;
1380         int idx;
1381
1382         if (tomoyo_init_request_info(&r, domain) == TOMOYO_CONFIG_DISABLED ||
1383             !path->mnt)
1384                 return 0;
1385         if (acc_mode == 0)
1386                 return 0;
1387         if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))
1388                 /*
1389                  * I don't check directories here because mkdir() and rmdir()
1390                  * don't call me.
1391                  */
1392                 return 0;
1393         idx = tomoyo_read_lock();
1394         buf = tomoyo_get_path(path);
1395         if (!buf)
1396                 goto out;
1397         error = 0;
1398         /*
1399          * If the filename is specified by "deny_rewrite" keyword,
1400          * we need to check "allow_rewrite" permission when the filename is not
1401          * opened for append mode or the filename is truncated at open time.
1402          */
1403         if ((acc_mode & MAY_WRITE) &&
1404             ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1405             (tomoyo_is_no_rewrite_file(buf))) {
1406                 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, buf);
1407         }
1408         if (!error)
1409                 error = tomoyo_file_perm(&r, buf, acc_mode);
1410         if (!error && (flag & O_TRUNC))
1411                 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, buf);
1412  out:
1413         kfree(buf);
1414         tomoyo_read_unlock(idx);
1415         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1416                 error = 0;
1417         return error;
1418 }
1419
1420 /**
1421  * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot", "mount" and "unmount".
1422  *
1423  * @operation: Type of operation.
1424  * @path:      Pointer to "struct path".
1425  *
1426  * Returns 0 on success, negative value otherwise.
1427  */
1428 int tomoyo_path_perm(const u8 operation, struct path *path)
1429 {
1430         int error = -ENOMEM;
1431         struct tomoyo_path_info *buf;
1432         struct tomoyo_request_info r;
1433         int idx;
1434
1435         if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1436             !path->mnt)
1437                 return 0;
1438         idx = tomoyo_read_lock();
1439         buf = tomoyo_get_path(path);
1440         if (!buf)
1441                 goto out;
1442         switch (operation) {
1443         case TOMOYO_TYPE_REWRITE:
1444                 if (!tomoyo_is_no_rewrite_file(buf)) {
1445                         error = 0;
1446                         goto out;
1447                 }
1448                 break;
1449         case TOMOYO_TYPE_RMDIR:
1450         case TOMOYO_TYPE_CHROOT:
1451                 if (!buf->is_dir) {
1452                         /*
1453                          * tomoyo_get_path() reserves space for appending "/."
1454                          */
1455                         strcat((char *) buf->name, "/");
1456                         tomoyo_fill_path_info(buf);
1457                 }
1458         }
1459         error = tomoyo_path_permission(&r, operation, buf);
1460  out:
1461         kfree(buf);
1462         tomoyo_read_unlock(idx);
1463         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1464                 error = 0;
1465         return error;
1466 }
1467
1468 /**
1469  * tomoyo_path_number3_perm2 - Check permission for path/number/number/number operation.
1470  *
1471  * @r:         Pointer to "struct tomoyo_request_info".
1472  * @operation: Type of operation.
1473  * @filename:  Filename to check.
1474  * @mode:      Create mode.
1475  * @dev:       Device number.
1476  *
1477  * Returns 0 on success, negative value otherwise.
1478  *
1479  * Caller holds tomoyo_read_lock().
1480  */
1481 static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r,
1482                                      const u8 operation,
1483                                      const struct tomoyo_path_info *filename,
1484                                      const unsigned int mode,
1485                                      const unsigned int dev)
1486 {
1487         int error;
1488         const unsigned int major = MAJOR(dev);
1489         const unsigned int minor = MINOR(dev);
1490
1491         error = tomoyo_path_number3_acl(r, filename, 1 << operation, mode,
1492                                         major, minor);
1493         if (!error)
1494                 return 0;
1495         tomoyo_warn_log(r, "%s %s 0%o %u %u",
1496                         tomoyo_path_number32keyword(operation),
1497                         filename->name, mode, major, minor);
1498         if (tomoyo_domain_quota_is_ok(r)) {
1499                 char mode_buf[64];
1500                 char major_buf[64];
1501                 char minor_buf[64];
1502                 memset(mode_buf, 0, sizeof(mode_buf));
1503                 memset(major_buf, 0, sizeof(major_buf));
1504                 memset(minor_buf, 0, sizeof(minor_buf));
1505                 snprintf(mode_buf, sizeof(mode_buf) - 1, "0%o", mode);
1506                 snprintf(major_buf, sizeof(major_buf) - 1, "%u", major);
1507                 snprintf(minor_buf, sizeof(minor_buf) - 1, "%u", minor);
1508                 tomoyo_update_path_number3_acl(operation,
1509                                                tomoyo_get_file_pattern(filename)
1510                                                ->name, mode_buf, major_buf,
1511                                                minor_buf, r->domain, false);
1512         }
1513         if (r->mode != TOMOYO_CONFIG_ENFORCING)
1514                 error = 0;
1515         return error;
1516 }
1517
1518 /**
1519  * tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar".
1520  *
1521  * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
1522  * @path:      Pointer to "struct path".
1523  * @mode:      Create mode.
1524  * @dev:       Device number.
1525  *
1526  * Returns 0 on success, negative value otherwise.
1527  */
1528 int tomoyo_path_number3_perm(const u8 operation, struct path *path,
1529                              const unsigned int mode, unsigned int dev)
1530 {
1531         struct tomoyo_request_info r;
1532         int error = -ENOMEM;
1533         struct tomoyo_path_info *buf;
1534         int idx;
1535
1536         if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1537             !path->mnt)
1538                 return 0;
1539         idx = tomoyo_read_lock();
1540         error = -ENOMEM;
1541         buf = tomoyo_get_path(path);
1542         if (buf) {
1543                 error = tomoyo_path_number3_perm2(&r, operation, buf, mode,
1544                                                   new_decode_dev(dev));
1545                 kfree(buf);
1546         }
1547         tomoyo_read_unlock(idx);
1548         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1549                 error = 0;
1550         return error;
1551 }
1552
1553 /**
1554  * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
1555  *
1556  * @operation: Type of operation.
1557  * @path1:      Pointer to "struct path".
1558  * @path2:      Pointer to "struct path".
1559  *
1560  * Returns 0 on success, negative value otherwise.
1561  */
1562 int tomoyo_path2_perm(const u8 operation, struct path *path1,
1563                       struct path *path2)
1564 {
1565         int error = -ENOMEM;
1566         struct tomoyo_path_info *buf1;
1567         struct tomoyo_path_info *buf2;
1568         struct tomoyo_request_info r;
1569         int idx;
1570
1571         if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1572             !path1->mnt || !path2->mnt)
1573                 return 0;
1574         idx = tomoyo_read_lock();
1575         buf1 = tomoyo_get_path(path1);
1576         buf2 = tomoyo_get_path(path2);
1577         if (!buf1 || !buf2)
1578                 goto out;
1579         {
1580                 struct dentry *dentry = path1->dentry;
1581                 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
1582                         /*
1583                          * tomoyo_get_path() reserves space for appending "/."
1584                          */
1585                         if (!buf1->is_dir) {
1586                                 strcat((char *) buf1->name, "/");
1587                                 tomoyo_fill_path_info(buf1);
1588                         }
1589                         if (!buf2->is_dir) {
1590                                 strcat((char *) buf2->name, "/");
1591                                 tomoyo_fill_path_info(buf2);
1592                         }
1593                 }
1594         }
1595         error = tomoyo_path2_acl(&r, operation, buf1, buf2);
1596         if (!error)
1597                 goto out;
1598         tomoyo_warn_log(&r, "%s %s %s", tomoyo_path22keyword(operation),
1599                         buf1->name, buf2->name);
1600         if (tomoyo_domain_quota_is_ok(&r)) {
1601                 const char *name1 = tomoyo_get_file_pattern(buf1)->name;
1602                 const char *name2 = tomoyo_get_file_pattern(buf2)->name;
1603                 tomoyo_update_path2_acl(operation, name1, name2, r.domain,
1604                                         false);
1605         }
1606  out:
1607         kfree(buf1);
1608         kfree(buf2);
1609         tomoyo_read_unlock(idx);
1610         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1611                 error = 0;
1612         return error;
1613 }
1614
1615 /**
1616  * tomoyo_write_file_policy - Update file related list.
1617  *
1618  * @data:      String to parse.
1619  * @domain:    Pointer to "struct tomoyo_domain_info".
1620  * @is_delete: True if it is a delete request.
1621  *
1622  * Returns 0 on success, negative value otherwise.
1623  *
1624  * Caller holds tomoyo_read_lock().
1625  */
1626 int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
1627                              const bool is_delete)
1628 {
1629         char *w[5];
1630         u8 type;
1631         if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
1632                 return -EINVAL;
1633         if (strncmp(w[0], "allow_", 6)) {
1634                 unsigned int perm;
1635                 if (sscanf(w[0], "%u", &perm) == 1)
1636                         return tomoyo_update_file_acl((u8) perm, w[1], domain,
1637                                                       is_delete);
1638                 goto out;
1639         }
1640         w[0] += 6;
1641         for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
1642                 if (strcmp(w[0], tomoyo_path_keyword[type]))
1643                         continue;
1644                 return tomoyo_update_path_acl(type, w[1], domain, is_delete);
1645         }
1646         if (!w[2][0])
1647                 goto out;
1648         for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
1649                 if (strcmp(w[0], tomoyo_path2_keyword[type]))
1650                         continue;
1651                 return tomoyo_update_path2_acl(type, w[1], w[2], domain,
1652                                                is_delete);
1653         }
1654         for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) {
1655                 if (strcmp(w[0], tomoyo_path_number_keyword[type]))
1656                         continue;
1657                 return tomoyo_update_path_number_acl(type, w[1], w[2], domain,
1658                                                      is_delete);
1659         }
1660         if (!w[3][0] || !w[4][0])
1661                 goto out;
1662         for (type = 0; type < TOMOYO_MAX_PATH_NUMBER3_OPERATION; type++) {
1663                 if (strcmp(w[0], tomoyo_path_number3_keyword[type]))
1664                         continue;
1665                 return tomoyo_update_path_number3_acl(type, w[1], w[2], w[3],
1666                                                       w[4], domain, is_delete);
1667         }
1668  out:
1669         return -EINVAL;
1670 }