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