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