xref: /openbmc/linux/security/tomoyo/common.h (revision fdb8ebb7)
19590837bSKentaro Takeda /*
29590837bSKentaro Takeda  * security/tomoyo/common.h
39590837bSKentaro Takeda  *
49590837bSKentaro Takeda  * Common functions for TOMOYO.
59590837bSKentaro Takeda  *
69590837bSKentaro Takeda  * Copyright (C) 2005-2009  NTT DATA CORPORATION
79590837bSKentaro Takeda  *
839826a1eSTetsuo Handa  * Version: 2.2.0   2009/04/01
99590837bSKentaro Takeda  *
109590837bSKentaro Takeda  */
119590837bSKentaro Takeda 
129590837bSKentaro Takeda #ifndef _SECURITY_TOMOYO_COMMON_H
139590837bSKentaro Takeda #define _SECURITY_TOMOYO_COMMON_H
149590837bSKentaro Takeda 
159590837bSKentaro Takeda #include <linux/ctype.h>
169590837bSKentaro Takeda #include <linux/string.h>
179590837bSKentaro Takeda #include <linux/mm.h>
189590837bSKentaro Takeda #include <linux/file.h>
199590837bSKentaro Takeda #include <linux/kmod.h>
209590837bSKentaro Takeda #include <linux/fs.h>
219590837bSKentaro Takeda #include <linux/sched.h>
229590837bSKentaro Takeda #include <linux/namei.h>
239590837bSKentaro Takeda #include <linux/mount.h>
249590837bSKentaro Takeda #include <linux/list.h>
259590837bSKentaro Takeda 
269590837bSKentaro Takeda struct dentry;
279590837bSKentaro Takeda struct vfsmount;
289590837bSKentaro Takeda 
29c3fa109aSTetsuo Handa /*
30c3fa109aSTetsuo Handa  * tomoyo_page_buffer is a structure which is used for holding a pathname
31c3fa109aSTetsuo Handa  * obtained from "struct dentry" and "struct vfsmount" pair.
32c3fa109aSTetsuo Handa  * As of now, it is 4096 bytes. If users complain that 4096 bytes is too small
33c3fa109aSTetsuo Handa  * (because TOMOYO escapes non ASCII printable characters using \ooo format),
34c3fa109aSTetsuo Handa  * we will make the buffer larger.
35c3fa109aSTetsuo Handa  */
369590837bSKentaro Takeda struct tomoyo_page_buffer {
379590837bSKentaro Takeda 	char buffer[4096];
389590837bSKentaro Takeda };
399590837bSKentaro Takeda 
40c3fa109aSTetsuo Handa /*
41c3fa109aSTetsuo Handa  * tomoyo_path_info is a structure which is used for holding a string data
42c3fa109aSTetsuo Handa  * used by TOMOYO.
43c3fa109aSTetsuo Handa  * This structure has several fields for supporting pattern matching.
44c3fa109aSTetsuo Handa  *
45c3fa109aSTetsuo Handa  * (1) "name" is the '\0' terminated string data.
46c3fa109aSTetsuo Handa  * (2) "hash" is full_name_hash(name, strlen(name)).
47c3fa109aSTetsuo Handa  *     This allows tomoyo_pathcmp() to compare by hash before actually compare
48c3fa109aSTetsuo Handa  *     using strcmp().
49c3fa109aSTetsuo Handa  * (3) "const_len" is the length of the initial segment of "name" which
50c3fa109aSTetsuo Handa  *     consists entirely of non wildcard characters. In other words, the length
51c3fa109aSTetsuo Handa  *     which we can compare two strings using strncmp().
52c3fa109aSTetsuo Handa  * (4) "is_dir" is a bool which is true if "name" ends with "/",
53c3fa109aSTetsuo Handa  *     false otherwise.
54c3fa109aSTetsuo Handa  *     TOMOYO distinguishes directory and non-directory. A directory ends with
55c3fa109aSTetsuo Handa  *     "/" and non-directory does not end with "/".
56c3fa109aSTetsuo Handa  * (5) "is_patterned" is a bool which is true if "name" contains wildcard
57c3fa109aSTetsuo Handa  *     characters, false otherwise. This allows TOMOYO to use "hash" and
58c3fa109aSTetsuo Handa  *     strcmp() for string comparison if "is_patterned" is false.
59c3fa109aSTetsuo Handa  */
609590837bSKentaro Takeda struct tomoyo_path_info {
619590837bSKentaro Takeda 	const char *name;
629590837bSKentaro Takeda 	u32 hash;          /* = full_name_hash(name, strlen(name)) */
639590837bSKentaro Takeda 	u16 const_len;     /* = tomoyo_const_part_length(name)     */
649590837bSKentaro Takeda 	bool is_dir;       /* = tomoyo_strendswith(name, "/")      */
659590837bSKentaro Takeda 	bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
669590837bSKentaro Takeda };
679590837bSKentaro Takeda 
689590837bSKentaro Takeda /*
699590837bSKentaro Takeda  * This is the max length of a token.
709590837bSKentaro Takeda  *
719590837bSKentaro Takeda  * A token consists of only ASCII printable characters.
729590837bSKentaro Takeda  * Non printable characters in a token is represented in \ooo style
739590837bSKentaro Takeda  * octal string. Thus, \ itself is represented as \\.
749590837bSKentaro Takeda  */
759590837bSKentaro Takeda #define TOMOYO_MAX_PATHNAME_LEN 4000
769590837bSKentaro Takeda 
77c3fa109aSTetsuo Handa /*
78c3fa109aSTetsuo Handa  * tomoyo_path_info_with_data is a structure which is used for holding a
79c3fa109aSTetsuo Handa  * pathname obtained from "struct dentry" and "struct vfsmount" pair.
80c3fa109aSTetsuo Handa  *
81c3fa109aSTetsuo Handa  * "struct tomoyo_path_info_with_data" consists of "struct tomoyo_path_info"
82c3fa109aSTetsuo Handa  * and buffer for the pathname, while "struct tomoyo_page_buffer" consists of
83c3fa109aSTetsuo Handa  * buffer for the pathname only.
84c3fa109aSTetsuo Handa  *
85c3fa109aSTetsuo Handa  * "struct tomoyo_path_info_with_data" is intended to allow TOMOYO to release
86c3fa109aSTetsuo Handa  * both "struct tomoyo_path_info" and buffer for the pathname by single kfree()
87c3fa109aSTetsuo Handa  * so that we don't need to return two pointers to the caller. If the caller
88c3fa109aSTetsuo Handa  * puts "struct tomoyo_path_info" on stack memory, we will be able to remove
89c3fa109aSTetsuo Handa  * "struct tomoyo_path_info_with_data".
90c3fa109aSTetsuo Handa  */
919590837bSKentaro Takeda struct tomoyo_path_info_with_data {
929590837bSKentaro Takeda 	/* Keep "head" first, for this pointer is passed to tomoyo_free(). */
939590837bSKentaro Takeda 	struct tomoyo_path_info head;
94a106cbfdSTetsuo Handa 	char barrier1[16]; /* Safeguard for overrun. */
959590837bSKentaro Takeda 	char body[TOMOYO_MAX_PATHNAME_LEN];
969590837bSKentaro Takeda 	char barrier2[16]; /* Safeguard for overrun. */
979590837bSKentaro Takeda };
989590837bSKentaro Takeda 
999590837bSKentaro Takeda /*
100c3fa109aSTetsuo Handa  * tomoyo_acl_info is a structure which is used for holding
101c3fa109aSTetsuo Handa  *
102c3fa109aSTetsuo Handa  *  (1) "list" which is linked to the ->acl_info_list of
103c3fa109aSTetsuo Handa  *      "struct tomoyo_domain_info"
104c3fa109aSTetsuo Handa  *  (2) "type" which tells
105c3fa109aSTetsuo Handa  *      (a) type & 0x7F : type of the entry (either
106c3fa109aSTetsuo Handa  *          "struct tomoyo_single_path_acl_record" or
107c3fa109aSTetsuo Handa  *          "struct tomoyo_double_path_acl_record")
108c3fa109aSTetsuo Handa  *      (b) type & 0x80 : whether the entry is marked as "deleted".
1099590837bSKentaro Takeda  *
1109590837bSKentaro Takeda  * Packing "struct tomoyo_acl_info" allows
111937bf613STetsuo Handa  * "struct tomoyo_single_path_acl_record" to embed "u8" + "u16" and
1129590837bSKentaro Takeda  * "struct tomoyo_double_path_acl_record" to embed "u8"
1139590837bSKentaro Takeda  * without enlarging their structure size.
1149590837bSKentaro Takeda  */
1159590837bSKentaro Takeda struct tomoyo_acl_info {
1169590837bSKentaro Takeda 	struct list_head list;
1179590837bSKentaro Takeda 	/*
1189590837bSKentaro Takeda 	 * Type of this ACL entry.
1199590837bSKentaro Takeda 	 *
1209590837bSKentaro Takeda 	 * MSB is is_deleted flag.
1219590837bSKentaro Takeda 	 */
1229590837bSKentaro Takeda 	u8 type;
1239590837bSKentaro Takeda } __packed;
1249590837bSKentaro Takeda 
1259590837bSKentaro Takeda /* This ACL entry is deleted.           */
1269590837bSKentaro Takeda #define TOMOYO_ACL_DELETED        0x80
1279590837bSKentaro Takeda 
128c3fa109aSTetsuo Handa /*
129c3fa109aSTetsuo Handa  * tomoyo_domain_info is a structure which is used for holding permissions
130c3fa109aSTetsuo Handa  * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
131c3fa109aSTetsuo Handa  * It has following fields.
132c3fa109aSTetsuo Handa  *
133c3fa109aSTetsuo Handa  *  (1) "list" which is linked to tomoyo_domain_list .
134c3fa109aSTetsuo Handa  *  (2) "acl_info_list" which is linked to "struct tomoyo_acl_info".
135c3fa109aSTetsuo Handa  *  (3) "domainname" which holds the name of the domain.
136c3fa109aSTetsuo Handa  *  (4) "profile" which remembers profile number assigned to this domain.
137c3fa109aSTetsuo Handa  *  (5) "is_deleted" is a bool which is true if this domain is marked as
138c3fa109aSTetsuo Handa  *      "deleted", false otherwise.
139c3fa109aSTetsuo Handa  *  (6) "quota_warned" is a bool which is used for suppressing warning message
140c3fa109aSTetsuo Handa  *      when learning mode learned too much entries.
141c3fa109aSTetsuo Handa  *  (7) "flags" which remembers this domain's attributes.
142c3fa109aSTetsuo Handa  *
143c3fa109aSTetsuo Handa  * A domain's lifecycle is an analogy of files on / directory.
144c3fa109aSTetsuo Handa  * Multiple domains with the same domainname cannot be created (as with
145c3fa109aSTetsuo Handa  * creating files with the same filename fails with -EEXIST).
146c3fa109aSTetsuo Handa  * If a process reached a domain, that process can reside in that domain after
147c3fa109aSTetsuo Handa  * that domain is marked as "deleted" (as with a process can access an already
148c3fa109aSTetsuo Handa  * open()ed file after that file was unlink()ed).
149c3fa109aSTetsuo Handa  */
1509590837bSKentaro Takeda struct tomoyo_domain_info {
1519590837bSKentaro Takeda 	struct list_head list;
1529590837bSKentaro Takeda 	struct list_head acl_info_list;
1539590837bSKentaro Takeda 	/* Name of this domain. Never NULL.          */
1549590837bSKentaro Takeda 	const struct tomoyo_path_info *domainname;
1559590837bSKentaro Takeda 	u8 profile;        /* Profile number to use. */
156a0558fc3STetsuo Handa 	bool is_deleted;   /* Delete flag.           */
1579590837bSKentaro Takeda 	bool quota_warned; /* Quota warnning flag.   */
1589590837bSKentaro Takeda 	/* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */
1599590837bSKentaro Takeda 	u8 flags;
1609590837bSKentaro Takeda };
1619590837bSKentaro Takeda 
1629590837bSKentaro Takeda /* Profile number is an integer between 0 and 255. */
1639590837bSKentaro Takeda #define TOMOYO_MAX_PROFILES 256
1649590837bSKentaro Takeda 
1659590837bSKentaro Takeda /* Ignore "allow_read" directive in exception policy. */
1669590837bSKentaro Takeda #define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1
1679590837bSKentaro Takeda /*
1689590837bSKentaro Takeda  * This domain was unable to create a new domain at tomoyo_find_next_domain()
1699590837bSKentaro Takeda  * because the name of the domain to be created was too long or
1709590837bSKentaro Takeda  * it could not allocate memory.
1719590837bSKentaro Takeda  * More than one process continued execve() without domain transition.
1729590837bSKentaro Takeda  */
1739590837bSKentaro Takeda #define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED        2
1749590837bSKentaro Takeda 
1759590837bSKentaro Takeda /*
176c3fa109aSTetsuo Handa  * tomoyo_single_path_acl_record is a structure which is used for holding an
177c3fa109aSTetsuo Handa  * entry with one pathname operation (e.g. open(), mkdir()).
178c3fa109aSTetsuo Handa  * It has following fields.
179c3fa109aSTetsuo Handa  *
180c3fa109aSTetsuo Handa  *  (1) "head" which is a "struct tomoyo_acl_info".
181c3fa109aSTetsuo Handa  *  (2) "perm" which is a bitmask of permitted operations.
182c3fa109aSTetsuo Handa  *  (3) "filename" is the pathname.
183c3fa109aSTetsuo Handa  *
184c3fa109aSTetsuo Handa  * Directives held by this structure are "allow_read/write", "allow_execute",
185c3fa109aSTetsuo Handa  * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
186c3fa109aSTetsuo Handa  * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
187937bf613STetsuo Handa  * "allow_mkchar", "allow_truncate", "allow_symlink", "allow_rewrite",
188937bf613STetsuo Handa  * "allow_chmod", "allow_chown", "allow_chgrp", "allow_chroot", "allow_mount"
189937bf613STetsuo Handa  * and "allow_unmount".
1909590837bSKentaro Takeda  */
1919590837bSKentaro Takeda struct tomoyo_single_path_acl_record {
1929590837bSKentaro Takeda 	struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */
193937bf613STetsuo Handa 	u8 perm_high;
1949590837bSKentaro Takeda 	u16 perm;
1959590837bSKentaro Takeda 	/* Pointer to single pathname. */
1969590837bSKentaro Takeda 	const struct tomoyo_path_info *filename;
1979590837bSKentaro Takeda };
1989590837bSKentaro Takeda 
199c3fa109aSTetsuo Handa /*
200c3fa109aSTetsuo Handa  * tomoyo_double_path_acl_record is a structure which is used for holding an
201937bf613STetsuo Handa  * entry with two pathnames operation (i.e. link(), rename() and pivot_root()).
202c3fa109aSTetsuo Handa  * It has following fields.
203c3fa109aSTetsuo Handa  *
204c3fa109aSTetsuo Handa  *  (1) "head" which is a "struct tomoyo_acl_info".
205c3fa109aSTetsuo Handa  *  (2) "perm" which is a bitmask of permitted operations.
206c3fa109aSTetsuo Handa  *  (3) "filename1" is the source/old pathname.
207c3fa109aSTetsuo Handa  *  (4) "filename2" is the destination/new pathname.
208c3fa109aSTetsuo Handa  *
209937bf613STetsuo Handa  * Directives held by this structure are "allow_rename", "allow_link" and
210937bf613STetsuo Handa  * "allow_pivot_root".
211c3fa109aSTetsuo Handa  */
2129590837bSKentaro Takeda struct tomoyo_double_path_acl_record {
2139590837bSKentaro Takeda 	struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */
2149590837bSKentaro Takeda 	u8 perm;
2159590837bSKentaro Takeda 	/* Pointer to single pathname. */
2169590837bSKentaro Takeda 	const struct tomoyo_path_info *filename1;
2179590837bSKentaro Takeda 	/* Pointer to single pathname. */
2189590837bSKentaro Takeda 	const struct tomoyo_path_info *filename2;
2199590837bSKentaro Takeda };
2209590837bSKentaro Takeda 
2219590837bSKentaro Takeda /* Keywords for ACLs. */
2229590837bSKentaro Takeda #define TOMOYO_KEYWORD_ALIAS                     "alias "
2239590837bSKentaro Takeda #define TOMOYO_KEYWORD_ALLOW_READ                "allow_read "
2249590837bSKentaro Takeda #define TOMOYO_KEYWORD_DELETE                    "delete "
2259590837bSKentaro Takeda #define TOMOYO_KEYWORD_DENY_REWRITE              "deny_rewrite "
2269590837bSKentaro Takeda #define TOMOYO_KEYWORD_FILE_PATTERN              "file_pattern "
2279590837bSKentaro Takeda #define TOMOYO_KEYWORD_INITIALIZE_DOMAIN         "initialize_domain "
2289590837bSKentaro Takeda #define TOMOYO_KEYWORD_KEEP_DOMAIN               "keep_domain "
2299590837bSKentaro Takeda #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN      "no_initialize_domain "
2309590837bSKentaro Takeda #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN            "no_keep_domain "
2319590837bSKentaro Takeda #define TOMOYO_KEYWORD_SELECT                    "select "
2329590837bSKentaro Takeda #define TOMOYO_KEYWORD_USE_PROFILE               "use_profile "
2339590837bSKentaro Takeda #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ  "ignore_global_allow_read"
2349590837bSKentaro Takeda /* A domain definition starts with <kernel>. */
2359590837bSKentaro Takeda #define TOMOYO_ROOT_NAME                         "<kernel>"
2369590837bSKentaro Takeda #define TOMOYO_ROOT_NAME_LEN                     (sizeof(TOMOYO_ROOT_NAME) - 1)
2379590837bSKentaro Takeda 
2389590837bSKentaro Takeda /* Index numbers for Access Controls. */
2399590837bSKentaro Takeda #define TOMOYO_MAC_FOR_FILE                  0  /* domain_policy.conf */
2409590837bSKentaro Takeda #define TOMOYO_MAX_ACCEPT_ENTRY              1
2419590837bSKentaro Takeda #define TOMOYO_VERBOSE                       2
2429590837bSKentaro Takeda #define TOMOYO_MAX_CONTROL_INDEX             3
2439590837bSKentaro Takeda 
244c3fa109aSTetsuo Handa /*
245c3fa109aSTetsuo Handa  * tomoyo_io_buffer is a structure which is used for reading and modifying
246c3fa109aSTetsuo Handa  * configuration via /sys/kernel/security/tomoyo/ interface.
247c3fa109aSTetsuo Handa  * It has many fields. ->read_var1 , ->read_var2 , ->write_var1 are used as
248c3fa109aSTetsuo Handa  * cursors.
249c3fa109aSTetsuo Handa  *
250c3fa109aSTetsuo Handa  * Since the content of /sys/kernel/security/tomoyo/domain_policy is a list of
251c3fa109aSTetsuo Handa  * "struct tomoyo_domain_info" entries and each "struct tomoyo_domain_info"
252c3fa109aSTetsuo Handa  * entry has a list of "struct tomoyo_acl_info", we need two cursors when
253c3fa109aSTetsuo Handa  * reading (one is for traversing tomoyo_domain_list and the other is for
254c3fa109aSTetsuo Handa  * traversing "struct tomoyo_acl_info"->acl_info_list ).
255c3fa109aSTetsuo Handa  *
256c3fa109aSTetsuo Handa  * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
257c3fa109aSTetsuo Handa  * "select ", TOMOYO seeks the cursor ->read_var1 and ->write_var1 to the
258c3fa109aSTetsuo Handa  * domain with the domainname specified by the rest of that line (NULL is set
259c3fa109aSTetsuo Handa  * if seek failed).
260c3fa109aSTetsuo Handa  * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
261c3fa109aSTetsuo Handa  * "delete ", TOMOYO deletes an entry or a domain specified by the rest of that
262c3fa109aSTetsuo Handa  * line (->write_var1 is set to NULL if a domain was deleted).
263c3fa109aSTetsuo Handa  * If a line written to /sys/kernel/security/tomoyo/domain_policy starts with
264c3fa109aSTetsuo Handa  * neither "select " nor "delete ", an entry or a domain specified by that line
265c3fa109aSTetsuo Handa  * is appended.
266c3fa109aSTetsuo Handa  */
2679590837bSKentaro Takeda struct tomoyo_io_buffer {
2689590837bSKentaro Takeda 	int (*read) (struct tomoyo_io_buffer *);
2699590837bSKentaro Takeda 	int (*write) (struct tomoyo_io_buffer *);
2709590837bSKentaro Takeda 	/* Exclusive lock for this structure.   */
2719590837bSKentaro Takeda 	struct mutex io_sem;
272fdb8ebb7STetsuo Handa 	/* Index returned by tomoyo_read_lock(). */
273fdb8ebb7STetsuo Handa 	int reader_idx;
2749590837bSKentaro Takeda 	/* The position currently reading from. */
2759590837bSKentaro Takeda 	struct list_head *read_var1;
2769590837bSKentaro Takeda 	/* Extra variables for reading.         */
2779590837bSKentaro Takeda 	struct list_head *read_var2;
2789590837bSKentaro Takeda 	/* The position currently writing to.   */
2799590837bSKentaro Takeda 	struct tomoyo_domain_info *write_var1;
2809590837bSKentaro Takeda 	/* The step for reading.                */
2819590837bSKentaro Takeda 	int read_step;
2829590837bSKentaro Takeda 	/* Buffer for reading.                  */
2839590837bSKentaro Takeda 	char *read_buf;
2849590837bSKentaro Takeda 	/* EOF flag for reading.                */
2859590837bSKentaro Takeda 	bool read_eof;
2869590837bSKentaro Takeda 	/* Read domain ACL of specified PID?    */
2879590837bSKentaro Takeda 	bool read_single_domain;
2889590837bSKentaro Takeda 	/* Extra variable for reading.          */
2899590837bSKentaro Takeda 	u8 read_bit;
2909590837bSKentaro Takeda 	/* Bytes available for reading.         */
2919590837bSKentaro Takeda 	int read_avail;
2929590837bSKentaro Takeda 	/* Size of read buffer.                 */
2939590837bSKentaro Takeda 	int readbuf_size;
2949590837bSKentaro Takeda 	/* Buffer for writing.                  */
2959590837bSKentaro Takeda 	char *write_buf;
2969590837bSKentaro Takeda 	/* Bytes available for writing.         */
2979590837bSKentaro Takeda 	int write_avail;
2989590837bSKentaro Takeda 	/* Size of write buffer.                */
2999590837bSKentaro Takeda 	int writebuf_size;
3009590837bSKentaro Takeda };
3019590837bSKentaro Takeda 
3029590837bSKentaro Takeda /* Check whether the domain has too many ACL entries to hold. */
3039590837bSKentaro Takeda bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain);
3049590837bSKentaro Takeda /* Transactional sprintf() for policy dump. */
3059590837bSKentaro Takeda bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
3069590837bSKentaro Takeda 	__attribute__ ((format(printf, 2, 3)));
3079590837bSKentaro Takeda /* Check whether the domainname is correct. */
3089590837bSKentaro Takeda bool tomoyo_is_correct_domain(const unsigned char *domainname,
3099590837bSKentaro Takeda 			      const char *function);
3109590837bSKentaro Takeda /* Check whether the token is correct. */
3119590837bSKentaro Takeda bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
3129590837bSKentaro Takeda 			    const s8 pattern_type, const s8 end_type,
3139590837bSKentaro Takeda 			    const char *function);
3149590837bSKentaro Takeda /* Check whether the token can be a domainname. */
3159590837bSKentaro Takeda bool tomoyo_is_domain_def(const unsigned char *buffer);
3169590837bSKentaro Takeda /* Check whether the given filename matches the given pattern. */
3179590837bSKentaro Takeda bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
3189590837bSKentaro Takeda 				 const struct tomoyo_path_info *pattern);
3199590837bSKentaro Takeda /* Read "alias" entry in exception policy. */
3209590837bSKentaro Takeda bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head);
3219590837bSKentaro Takeda /*
3229590837bSKentaro Takeda  * Read "initialize_domain" and "no_initialize_domain" entry
3239590837bSKentaro Takeda  * in exception policy.
3249590837bSKentaro Takeda  */
3259590837bSKentaro Takeda bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head);
3269590837bSKentaro Takeda /* Read "keep_domain" and "no_keep_domain" entry in exception policy. */
3279590837bSKentaro Takeda bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head);
3289590837bSKentaro Takeda /* Read "file_pattern" entry in exception policy. */
3299590837bSKentaro Takeda bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head);
3309590837bSKentaro Takeda /* Read "allow_read" entry in exception policy. */
3319590837bSKentaro Takeda bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head);
3329590837bSKentaro Takeda /* Read "deny_rewrite" entry in exception policy. */
3339590837bSKentaro Takeda bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head);
3349590837bSKentaro Takeda /* Write domain policy violation warning message to console? */
3359590837bSKentaro Takeda bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
3369590837bSKentaro Takeda /* Convert double path operation to operation name. */
3379590837bSKentaro Takeda const char *tomoyo_dp2keyword(const u8 operation);
3389590837bSKentaro Takeda /* Get the last component of the given domainname. */
3399590837bSKentaro Takeda const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
3409590837bSKentaro Takeda /* Get warning message. */
3419590837bSKentaro Takeda const char *tomoyo_get_msg(const bool is_enforce);
3429590837bSKentaro Takeda /* Convert single path operation to operation name. */
3439590837bSKentaro Takeda const char *tomoyo_sp2keyword(const u8 operation);
3449590837bSKentaro Takeda /* Create "alias" entry in exception policy. */
3459590837bSKentaro Takeda int tomoyo_write_alias_policy(char *data, const bool is_delete);
3469590837bSKentaro Takeda /*
3479590837bSKentaro Takeda  * Create "initialize_domain" and "no_initialize_domain" entry
3489590837bSKentaro Takeda  * in exception policy.
3499590837bSKentaro Takeda  */
3509590837bSKentaro Takeda int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
3519590837bSKentaro Takeda 					   const bool is_delete);
3529590837bSKentaro Takeda /* Create "keep_domain" and "no_keep_domain" entry in exception policy. */
3539590837bSKentaro Takeda int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
3549590837bSKentaro Takeda 				      const bool is_delete);
3559590837bSKentaro Takeda /*
3569590837bSKentaro Takeda  * Create "allow_read/write", "allow_execute", "allow_read", "allow_write",
3579590837bSKentaro Takeda  * "allow_create", "allow_unlink", "allow_mkdir", "allow_rmdir",
3589590837bSKentaro Takeda  * "allow_mkfifo", "allow_mksock", "allow_mkblock", "allow_mkchar",
3599590837bSKentaro Takeda  * "allow_truncate", "allow_symlink", "allow_rewrite", "allow_rename" and
3609590837bSKentaro Takeda  * "allow_link" entry in domain policy.
3619590837bSKentaro Takeda  */
3629590837bSKentaro Takeda int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
3639590837bSKentaro Takeda 			     const bool is_delete);
3649590837bSKentaro Takeda /* Create "allow_read" entry in exception policy. */
3659590837bSKentaro Takeda int tomoyo_write_globally_readable_policy(char *data, const bool is_delete);
3669590837bSKentaro Takeda /* Create "deny_rewrite" entry in exception policy. */
3679590837bSKentaro Takeda int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete);
3689590837bSKentaro Takeda /* Create "file_pattern" entry in exception policy. */
3699590837bSKentaro Takeda int tomoyo_write_pattern_policy(char *data, const bool is_delete);
3709590837bSKentaro Takeda /* Find a domain by the given name. */
3719590837bSKentaro Takeda struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
3729590837bSKentaro Takeda /* Find or create a domain by the given name. */
3739590837bSKentaro Takeda struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
3749590837bSKentaro Takeda 							    domainname,
3759590837bSKentaro Takeda 							    const u8 profile);
3769590837bSKentaro Takeda /* Check mode for specified functionality. */
3779590837bSKentaro Takeda unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
3789590837bSKentaro Takeda 				const u8 index);
3799590837bSKentaro Takeda /* Allocate memory for structures. */
3809590837bSKentaro Takeda void *tomoyo_alloc_acl_element(const u8 acl_type);
3819590837bSKentaro Takeda /* Fill in "struct tomoyo_path_info" members. */
3829590837bSKentaro Takeda void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
3839590837bSKentaro Takeda /* Run policy loader when /sbin/init starts. */
3849590837bSKentaro Takeda void tomoyo_load_policy(const char *filename);
3859590837bSKentaro Takeda /* Change "struct tomoyo_domain_info"->flags. */
3869590837bSKentaro Takeda void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
3879590837bSKentaro Takeda 			    const bool is_delete, const u8 flags);
3889590837bSKentaro Takeda 
3899590837bSKentaro Takeda /* strcmp() for "struct tomoyo_path_info" structure. */
3909590837bSKentaro Takeda static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
3919590837bSKentaro Takeda 				  const struct tomoyo_path_info *b)
3929590837bSKentaro Takeda {
3939590837bSKentaro Takeda 	return a->hash != b->hash || strcmp(a->name, b->name);
3949590837bSKentaro Takeda }
3959590837bSKentaro Takeda 
3969590837bSKentaro Takeda /* Get type of an ACL entry. */
3979590837bSKentaro Takeda static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr)
3989590837bSKentaro Takeda {
3999590837bSKentaro Takeda 	return ptr->type & ~TOMOYO_ACL_DELETED;
4009590837bSKentaro Takeda }
4019590837bSKentaro Takeda 
4029590837bSKentaro Takeda /* Get type of an ACL entry. */
4039590837bSKentaro Takeda static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr)
4049590837bSKentaro Takeda {
4059590837bSKentaro Takeda 	return ptr->type;
4069590837bSKentaro Takeda }
4079590837bSKentaro Takeda 
4089590837bSKentaro Takeda /**
4099590837bSKentaro Takeda  * tomoyo_is_valid - Check whether the character is a valid char.
4109590837bSKentaro Takeda  *
4119590837bSKentaro Takeda  * @c: The character to check.
4129590837bSKentaro Takeda  *
4139590837bSKentaro Takeda  * Returns true if @c is a valid character, false otherwise.
4149590837bSKentaro Takeda  */
4159590837bSKentaro Takeda static inline bool tomoyo_is_valid(const unsigned char c)
4169590837bSKentaro Takeda {
4179590837bSKentaro Takeda 	return c > ' ' && c < 127;
4189590837bSKentaro Takeda }
4199590837bSKentaro Takeda 
4209590837bSKentaro Takeda /**
4219590837bSKentaro Takeda  * tomoyo_is_invalid - Check whether the character is an invalid char.
4229590837bSKentaro Takeda  *
4239590837bSKentaro Takeda  * @c: The character to check.
4249590837bSKentaro Takeda  *
4259590837bSKentaro Takeda  * Returns true if @c is an invalid character, false otherwise.
4269590837bSKentaro Takeda  */
4279590837bSKentaro Takeda static inline bool tomoyo_is_invalid(const unsigned char c)
4289590837bSKentaro Takeda {
4299590837bSKentaro Takeda 	return c && (c <= ' ' || c >= 127);
4309590837bSKentaro Takeda }
4319590837bSKentaro Takeda 
4329590837bSKentaro Takeda /* The list for "struct tomoyo_domain_info". */
4339590837bSKentaro Takeda extern struct list_head tomoyo_domain_list;
4349590837bSKentaro Takeda extern struct rw_semaphore tomoyo_domain_list_lock;
4359590837bSKentaro Takeda 
4369590837bSKentaro Takeda /* Lock for domain->acl_info_list. */
4379590837bSKentaro Takeda extern struct rw_semaphore tomoyo_domain_acl_info_list_lock;
4389590837bSKentaro Takeda 
4399590837bSKentaro Takeda /* Has /sbin/init started? */
4409590837bSKentaro Takeda extern bool tomoyo_policy_loaded;
4419590837bSKentaro Takeda 
4429590837bSKentaro Takeda /* The kernel's domain. */
4439590837bSKentaro Takeda extern struct tomoyo_domain_info tomoyo_kernel_domain;
4449590837bSKentaro Takeda 
4459590837bSKentaro Takeda /**
4469590837bSKentaro Takeda  * list_for_each_cookie - iterate over a list with cookie.
4479590837bSKentaro Takeda  * @pos:        the &struct list_head to use as a loop cursor.
4489590837bSKentaro Takeda  * @cookie:     the &struct list_head to use as a cookie.
4499590837bSKentaro Takeda  * @head:       the head for your list.
4509590837bSKentaro Takeda  *
451fdb8ebb7STetsuo Handa  * Same with list_for_each_rcu() except that this primitive uses @cookie
4529590837bSKentaro Takeda  * so that we can continue iteration.
4539590837bSKentaro Takeda  * @cookie must be NULL when iteration starts, and @cookie will become
4549590837bSKentaro Takeda  * NULL when iteration finishes.
4559590837bSKentaro Takeda  */
4569590837bSKentaro Takeda #define list_for_each_cookie(pos, cookie, head)				\
4579590837bSKentaro Takeda 	for (({ if (!cookie)						\
4589590837bSKentaro Takeda 				     cookie = head; }),			\
459fdb8ebb7STetsuo Handa 		     pos = rcu_dereference((cookie)->next);		\
4609590837bSKentaro Takeda 	     prefetch(pos->next), pos != (head) || ((cookie) = NULL);	\
461fdb8ebb7STetsuo Handa 	     (cookie) = pos, pos = rcu_dereference(pos->next))
462fdb8ebb7STetsuo Handa 
463fdb8ebb7STetsuo Handa extern struct srcu_struct tomoyo_ss;
464fdb8ebb7STetsuo Handa 
465fdb8ebb7STetsuo Handa static inline int tomoyo_read_lock(void)
466fdb8ebb7STetsuo Handa {
467fdb8ebb7STetsuo Handa 	return srcu_read_lock(&tomoyo_ss);
468fdb8ebb7STetsuo Handa }
469fdb8ebb7STetsuo Handa 
470fdb8ebb7STetsuo Handa static inline void tomoyo_read_unlock(int idx)
471fdb8ebb7STetsuo Handa {
472fdb8ebb7STetsuo Handa 	srcu_read_unlock(&tomoyo_ss, idx);
473fdb8ebb7STetsuo Handa }
4749590837bSKentaro Takeda 
4759590837bSKentaro Takeda #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
476