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