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