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