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