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