]> bbs.cooldavid.org Git - net-next-2.6.git/blob - security/tomoyo/file.c
TOMOYO: Pass parameters via structure.
[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         r->param_type = TOMOYO_TYPE_PATH_ACL;
977         r->param.path.filename = filename;
978         r->param.path.operation = operation;
979         do {
980                 error = tomoyo_path_acl(r, filename, 1 << operation);
981                 if (error && operation == TOMOYO_TYPE_READ &&
982                     !r->domain->ignore_global_allow_read &&
983                     tomoyo_is_globally_readable_file(filename))
984                         error = 0;
985                 if (!error)
986                         break;
987                 msg = tomoyo_path2keyword(operation);
988                 tomoyo_warn_log(r, "%s %s", msg, filename->name);
989                 error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
990                                           tomoyo_file_pattern(filename));
991                 /*
992                  * Do not retry for execute request, for alias may have
993                  * changed.
994                  */
995         } while (error == TOMOYO_RETRY_REQUEST &&
996                  operation != TOMOYO_TYPE_EXECUTE);
997         /*
998          * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
999          * we need to check "allow_rewrite" permission if the filename is
1000          * specified by "deny_rewrite" keyword.
1001          */
1002         if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
1003             tomoyo_is_no_rewrite_file(filename)) {
1004                 operation = TOMOYO_TYPE_REWRITE;
1005                 goto next;
1006         }
1007         return error;
1008 }
1009
1010 /**
1011  * tomoyo_path_number_acl - Check permission for ioctl/chmod/chown/chgrp operation.
1012  *
1013  * @r:        Pointer to "struct tomoyo_request_info".
1014  * @type:     Operation.
1015  * @filename: Filename to check.
1016  * @number:   Number.
1017  *
1018  * Returns 0 on success, -EPERM otherwise.
1019  *
1020  * Caller holds tomoyo_read_lock().
1021  */
1022 static int tomoyo_path_number_acl(struct tomoyo_request_info *r, const u8 type,
1023                                   const struct tomoyo_path_info *filename,
1024                                   const unsigned long number)
1025 {
1026         struct tomoyo_domain_info *domain = r->domain;
1027         struct tomoyo_acl_info *ptr;
1028         const u8 perm = 1 << type;
1029         int error = -EPERM;
1030         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1031                 struct tomoyo_path_number_acl *acl;
1032                 if (ptr->type != TOMOYO_TYPE_PATH_NUMBER_ACL)
1033                         continue;
1034                 acl = container_of(ptr, struct tomoyo_path_number_acl,
1035                                    head);
1036                 if (!(acl->perm & perm) ||
1037                     !tomoyo_compare_number_union(number, &acl->number) ||
1038                     !tomoyo_compare_name_union(filename, &acl->name))
1039                         continue;
1040                 error = 0;
1041                 break;
1042         }
1043         return error;
1044 }
1045
1046 static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
1047                                         const struct tomoyo_acl_info *b)
1048 {
1049         const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
1050                                                                head);
1051         const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
1052                                                                head);
1053         return tomoyo_is_same_acl_head(&p1->head, &p2->head)
1054                 && tomoyo_is_same_name_union(&p1->name, &p2->name)
1055                 && tomoyo_is_same_number_union(&p1->number, &p2->number);
1056 }
1057
1058 static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
1059                                          struct tomoyo_acl_info *b,
1060                                          const bool is_delete)
1061 {
1062         u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
1063                                           head)->perm;
1064         u8 perm = *a_perm;
1065         const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
1066                 ->perm;
1067         if (is_delete)
1068                 perm &= ~b_perm;
1069         else
1070                 perm |= b_perm;
1071         *a_perm = perm;
1072         return !perm;
1073 }
1074
1075 /**
1076  * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
1077  *
1078  * @type:      Type of operation.
1079  * @filename:  Filename.
1080  * @number:    Number.
1081  * @domain:    Pointer to "struct tomoyo_domain_info".
1082  * @is_delete: True if it is a delete request.
1083  *
1084  * Returns 0 on success, negative value otherwise.
1085  */
1086 static int tomoyo_update_path_number_acl(const u8 type, const char *filename,
1087                                          char *number,
1088                                          struct tomoyo_domain_info * const
1089                                          domain,
1090                                          const bool is_delete)
1091 {
1092         struct tomoyo_path_number_acl e = {
1093                 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
1094                 .perm = 1 << type
1095         };
1096         int error = is_delete ? -ENOENT : -ENOMEM;
1097         if (!tomoyo_parse_name_union(filename, &e.name))
1098                 return -EINVAL;
1099         if (!tomoyo_parse_number_union(number, &e.number))
1100                 goto out;
1101         error = tomoyo_update_domain(&e.head, sizeof(e), is_delete, domain,
1102                                      tomoyo_same_path_number_acl,
1103                                      tomoyo_merge_path_number_acl);
1104  out:
1105         tomoyo_put_name_union(&e.name);
1106         tomoyo_put_number_union(&e.number);
1107         return error;
1108 }
1109
1110 /**
1111  * tomoyo_path_number_perm2 - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
1112  *
1113  * @r:        Pointer to "strct tomoyo_request_info".
1114  * @filename: Filename to check.
1115  * @number:   Number.
1116  *
1117  * Returns 0 on success, negative value otherwise.
1118  *
1119  * Caller holds tomoyo_read_lock().
1120  */
1121 static int tomoyo_path_number_perm2(struct tomoyo_request_info *r,
1122                                     const u8 type,
1123                                     const struct tomoyo_path_info *filename,
1124                                     const unsigned long number)
1125 {
1126         char buffer[64];
1127         int error;
1128         u8 radix;
1129         const char *msg;
1130
1131         if (!filename)
1132                 return 0;
1133         switch (type) {
1134         case TOMOYO_TYPE_CREATE:
1135         case TOMOYO_TYPE_MKDIR:
1136         case TOMOYO_TYPE_MKFIFO:
1137         case TOMOYO_TYPE_MKSOCK:
1138         case TOMOYO_TYPE_CHMOD:
1139                 radix = TOMOYO_VALUE_TYPE_OCTAL;
1140                 break;
1141         case TOMOYO_TYPE_IOCTL:
1142                 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
1143                 break;
1144         default:
1145                 radix = TOMOYO_VALUE_TYPE_DECIMAL;
1146                 break;
1147         }
1148         tomoyo_print_ulong(buffer, sizeof(buffer), number, radix);
1149         r->param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
1150         r->param.path_number.operation = type;
1151         r->param.path_number.filename = filename;
1152         r->param.path_number.number = number;
1153         do {
1154                 error = tomoyo_path_number_acl(r, type, filename, number);
1155                 if (!error)
1156                         break;
1157                 msg = tomoyo_path_number2keyword(type);
1158                 tomoyo_warn_log(r, "%s %s %s", msg, filename->name, buffer);
1159                 error = tomoyo_supervisor(r, "allow_%s %s %s\n", msg,
1160                                           tomoyo_file_pattern(filename),
1161                                           buffer);
1162         } while (error == TOMOYO_RETRY_REQUEST);
1163         return error;
1164 }
1165
1166 /**
1167  * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
1168  *
1169  * @type:   Type of operation.
1170  * @path:   Pointer to "struct path".
1171  * @number: Number.
1172  *
1173  * Returns 0 on success, negative value otherwise.
1174  */
1175 int tomoyo_path_number_perm(const u8 type, struct path *path,
1176                             unsigned long number)
1177 {
1178         struct tomoyo_request_info r;
1179         int error = -ENOMEM;
1180         struct tomoyo_path_info buf;
1181         int idx;
1182
1183         if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
1184             == TOMOYO_CONFIG_DISABLED || !path->mnt || !path->dentry)
1185                 return 0;
1186         idx = tomoyo_read_lock();
1187         if (!tomoyo_get_realpath(&buf, path))
1188                 goto out;
1189         if (type == TOMOYO_TYPE_MKDIR)
1190                 tomoyo_add_slash(&buf);
1191         error = tomoyo_path_number_perm2(&r, type, &buf, number);
1192  out:
1193         kfree(buf.name);
1194         tomoyo_read_unlock(idx);
1195         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1196                 error = 0;
1197         return error;
1198 }
1199
1200 /**
1201  * tomoyo_check_open_permission - Check permission for "read" and "write".
1202  *
1203  * @domain: Pointer to "struct tomoyo_domain_info".
1204  * @path:   Pointer to "struct path".
1205  * @flag:   Flags for open().
1206  *
1207  * Returns 0 on success, negative value otherwise.
1208  */
1209 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1210                                  struct path *path, const int flag)
1211 {
1212         const u8 acc_mode = ACC_MODE(flag);
1213         int error = -ENOMEM;
1214         struct tomoyo_path_info buf;
1215         struct tomoyo_request_info r;
1216         int idx;
1217
1218         if (!path->mnt ||
1219             (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode)))
1220                 return 0;
1221         buf.name = NULL;
1222         r.mode = TOMOYO_CONFIG_DISABLED;
1223         idx = tomoyo_read_lock();
1224         if (!tomoyo_get_realpath(&buf, path))
1225                 goto out;
1226         error = 0;
1227         /*
1228          * If the filename is specified by "deny_rewrite" keyword,
1229          * we need to check "allow_rewrite" permission when the filename is not
1230          * opened for append mode or the filename is truncated at open time.
1231          */
1232         if ((acc_mode & MAY_WRITE) && !(flag & O_APPEND)
1233             && tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_REWRITE)
1234             != TOMOYO_CONFIG_DISABLED) {
1235                 if (!tomoyo_get_realpath(&buf, path)) {
1236                         error = -ENOMEM;
1237                         goto out;
1238                 }
1239                 if (tomoyo_is_no_rewrite_file(&buf))
1240                         error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE,
1241                                                        &buf);
1242         }
1243         if (!error && acc_mode &&
1244             tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
1245             != TOMOYO_CONFIG_DISABLED) {
1246                 u8 operation;
1247                 if (!buf.name && !tomoyo_get_realpath(&buf, path)) {
1248                         error = -ENOMEM;
1249                         goto out;
1250                 }
1251                 if (acc_mode == (MAY_READ | MAY_WRITE))
1252                         operation = TOMOYO_TYPE_READ_WRITE;
1253                 else if (acc_mode == MAY_READ)
1254                         operation = TOMOYO_TYPE_READ;
1255                 else
1256                         operation = TOMOYO_TYPE_WRITE;
1257                 error = tomoyo_path_permission(&r, operation, &buf);
1258         }
1259  out:
1260         kfree(buf.name);
1261         tomoyo_read_unlock(idx);
1262         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1263                 error = 0;
1264         return error;
1265 }
1266
1267 /**
1268  * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "rewrite", "chroot" and "unmount".
1269  *
1270  * @operation: Type of operation.
1271  * @path:      Pointer to "struct path".
1272  *
1273  * Returns 0 on success, negative value otherwise.
1274  */
1275 int tomoyo_path_perm(const u8 operation, struct path *path)
1276 {
1277         int error = -ENOMEM;
1278         struct tomoyo_path_info buf;
1279         struct tomoyo_request_info r;
1280         int idx;
1281
1282         if (!path->mnt)
1283                 return 0;
1284         if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
1285             == TOMOYO_CONFIG_DISABLED)
1286                 return 0;
1287         buf.name = NULL;
1288         idx = tomoyo_read_lock();
1289         if (!tomoyo_get_realpath(&buf, path))
1290                 goto out;
1291         switch (operation) {
1292         case TOMOYO_TYPE_REWRITE:
1293                 if (!tomoyo_is_no_rewrite_file(&buf)) {
1294                         error = 0;
1295                         goto out;
1296                 }
1297                 break;
1298         case TOMOYO_TYPE_RMDIR:
1299         case TOMOYO_TYPE_CHROOT:
1300         case TOMOYO_TYPE_UMOUNT:
1301                 tomoyo_add_slash(&buf);
1302                 break;
1303         }
1304         error = tomoyo_path_permission(&r, operation, &buf);
1305  out:
1306         kfree(buf.name);
1307         tomoyo_read_unlock(idx);
1308         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1309                 error = 0;
1310         return error;
1311 }
1312
1313 /**
1314  * tomoyo_path_number3_perm2 - Check permission for path/number/number/number operation.
1315  *
1316  * @r:         Pointer to "struct tomoyo_request_info".
1317  * @operation: Type of operation.
1318  * @filename:  Filename to check.
1319  * @mode:      Create mode.
1320  * @dev:       Device number.
1321  *
1322  * Returns 0 on success, negative value otherwise.
1323  *
1324  * Caller holds tomoyo_read_lock().
1325  */
1326 static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r,
1327                                      const u8 operation,
1328                                      const struct tomoyo_path_info *filename,
1329                                      const unsigned int mode,
1330                                      const unsigned int dev)
1331 {
1332         int error;
1333         const char *msg;
1334         const unsigned int major = MAJOR(dev);
1335         const unsigned int minor = MINOR(dev);
1336
1337         do {
1338                 error = tomoyo_path_number3_acl(r, filename, 1 << operation,
1339                                                 mode, major, minor);
1340                 if (!error)
1341                         break;
1342                 msg = tomoyo_path_number32keyword(operation);
1343                 tomoyo_warn_log(r, "%s %s 0%o %u %u", msg, filename->name,
1344                                 mode, major, minor);
1345                 error = tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", msg,
1346                                           tomoyo_file_pattern(filename), mode,
1347                                           major, minor);
1348         } while (error == TOMOYO_RETRY_REQUEST);
1349         if (r->mode != TOMOYO_CONFIG_ENFORCING)
1350                 error = 0;
1351         return error;
1352 }
1353
1354 /**
1355  * tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar".
1356  *
1357  * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
1358  * @path:      Pointer to "struct path".
1359  * @mode:      Create mode.
1360  * @dev:       Device number.
1361  *
1362  * Returns 0 on success, negative value otherwise.
1363  */
1364 int tomoyo_path_number3_perm(const u8 operation, struct path *path,
1365                              const unsigned int mode, unsigned int dev)
1366 {
1367         struct tomoyo_request_info r;
1368         int error = -ENOMEM;
1369         struct tomoyo_path_info buf;
1370         int idx;
1371
1372         if (!path->mnt ||
1373             tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
1374             == TOMOYO_CONFIG_DISABLED)
1375                 return 0;
1376         idx = tomoyo_read_lock();
1377         error = -ENOMEM;
1378         if (tomoyo_get_realpath(&buf, path)) {
1379                 dev = new_decode_dev(dev);
1380                 r.param_type = TOMOYO_TYPE_PATH_NUMBER3_ACL;
1381                 r.param.mkdev.filename = &buf;
1382                 r.param.mkdev.operation = operation;
1383                 r.param.mkdev.mode = mode;
1384                 r.param.mkdev.major = MAJOR(dev);
1385                 r.param.mkdev.minor = MINOR(dev);
1386                 error = tomoyo_path_number3_perm2(&r, operation, &buf, mode,
1387                                                   dev);
1388                 kfree(buf.name);
1389         }
1390         tomoyo_read_unlock(idx);
1391         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1392                 error = 0;
1393         return error;
1394 }
1395
1396 /**
1397  * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
1398  *
1399  * @operation: Type of operation.
1400  * @path1:      Pointer to "struct path".
1401  * @path2:      Pointer to "struct path".
1402  *
1403  * Returns 0 on success, negative value otherwise.
1404  */
1405 int tomoyo_path2_perm(const u8 operation, struct path *path1,
1406                       struct path *path2)
1407 {
1408         int error = -ENOMEM;
1409         const char *msg;
1410         struct tomoyo_path_info buf1;
1411         struct tomoyo_path_info buf2;
1412         struct tomoyo_request_info r;
1413         int idx;
1414
1415         if (!path1->mnt || !path2->mnt ||
1416             tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
1417             == TOMOYO_CONFIG_DISABLED)
1418                 return 0;
1419         buf1.name = NULL;
1420         buf2.name = NULL;
1421         idx = tomoyo_read_lock();
1422         if (!tomoyo_get_realpath(&buf1, path1) ||
1423             !tomoyo_get_realpath(&buf2, path2))
1424                 goto out;
1425         switch (operation) {
1426                 struct dentry *dentry;
1427         case TOMOYO_TYPE_RENAME:
1428         case TOMOYO_TYPE_LINK:
1429                 dentry = path1->dentry;
1430                 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
1431                         break;
1432                 /* fall through */
1433         case TOMOYO_TYPE_PIVOT_ROOT:
1434                 tomoyo_add_slash(&buf1);
1435                 tomoyo_add_slash(&buf2);
1436                 break;
1437         }
1438         r.param_type = TOMOYO_TYPE_PATH2_ACL;
1439         r.param.path2.operation = operation;
1440         r.param.path2.filename1 = &buf1;
1441         r.param.path2.filename2 = &buf2;
1442         do {
1443                 error = tomoyo_path2_acl(&r, operation, &buf1, &buf2);
1444                 if (!error)
1445                         break;
1446                 msg = tomoyo_path22keyword(operation);
1447                 tomoyo_warn_log(&r, "%s %s %s", msg, buf1.name, buf2.name);
1448                 error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg,
1449                                           tomoyo_file_pattern(&buf1),
1450                                           tomoyo_file_pattern(&buf2));
1451         } while (error == TOMOYO_RETRY_REQUEST);
1452  out:
1453         kfree(buf1.name);
1454         kfree(buf2.name);
1455         tomoyo_read_unlock(idx);
1456         if (r.mode != TOMOYO_CONFIG_ENFORCING)
1457                 error = 0;
1458         return error;
1459 }
1460
1461 /**
1462  * tomoyo_write_file_policy - Update file related list.
1463  *
1464  * @data:      String to parse.
1465  * @domain:    Pointer to "struct tomoyo_domain_info".
1466  * @is_delete: True if it is a delete request.
1467  *
1468  * Returns 0 on success, negative value otherwise.
1469  *
1470  * Caller holds tomoyo_read_lock().
1471  */
1472 int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
1473                              const bool is_delete)
1474 {
1475         char *w[5];
1476         u8 type;
1477         if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
1478                 return -EINVAL;
1479         if (strncmp(w[0], "allow_", 6))
1480                 goto out;
1481         w[0] += 6;
1482         for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
1483                 if (strcmp(w[0], tomoyo_path_keyword[type]))
1484                         continue;
1485                 return tomoyo_update_path_acl(type, w[1], domain, is_delete);
1486         }
1487         if (!w[2][0])
1488                 goto out;
1489         for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
1490                 if (strcmp(w[0], tomoyo_path2_keyword[type]))
1491                         continue;
1492                 return tomoyo_update_path2_acl(type, w[1], w[2], domain,
1493                                                is_delete);
1494         }
1495         for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) {
1496                 if (strcmp(w[0], tomoyo_path_number_keyword[type]))
1497                         continue;
1498                 return tomoyo_update_path_number_acl(type, w[1], w[2], domain,
1499                                                      is_delete);
1500         }
1501         if (!w[3][0] || !w[4][0])
1502                 goto out;
1503         for (type = 0; type < TOMOYO_MAX_PATH_NUMBER3_OPERATION; type++) {
1504                 if (strcmp(w[0], tomoyo_path_number3_keyword[type]))
1505                         continue;
1506                 return tomoyo_update_path_number3_acl(type, w[1], w[2], w[3],
1507                                                       w[4], domain, is_delete);
1508         }
1509  out:
1510         return -EINVAL;
1511 }