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