Commit 0f2a55d5bb2372058275b0b343d90dd5d640d045

Authored by Tetsuo Handa
Committed by James Morris
1 parent c920669345

TOMOYO: Update kernel-doc.

Update comments for scripts/kernel-doc and fix some of errors reported by
scripts/checkpatch.pl .

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 13 changed files with 269 additions and 62 deletions Inline Diff

security/tomoyo/audit.c
1 /* 1 /*
2 * security/tomoyo/audit.c 2 * security/tomoyo/audit.c
3 * 3 *
4 * Pathname restriction functions. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include "common.h" 7 #include "common.h"
10 #include <linux/slab.h> 8 #include <linux/slab.h>
11 9
12 /** 10 /**
13 * tomoyo_print_bprm - Print "struct linux_binprm" for auditing. 11 * tomoyo_print_bprm - Print "struct linux_binprm" for auditing.
14 * 12 *
15 * @bprm: Pointer to "struct linux_binprm". 13 * @bprm: Pointer to "struct linux_binprm".
16 * @dump: Pointer to "struct tomoyo_page_dump". 14 * @dump: Pointer to "struct tomoyo_page_dump".
17 * 15 *
18 * Returns the contents of @bprm on success, NULL otherwise. 16 * Returns the contents of @bprm on success, NULL otherwise.
19 * 17 *
20 * This function uses kzalloc(), so caller must kfree() if this function 18 * This function uses kzalloc(), so caller must kfree() if this function
21 * didn't return NULL. 19 * didn't return NULL.
22 */ 20 */
23 static char *tomoyo_print_bprm(struct linux_binprm *bprm, 21 static char *tomoyo_print_bprm(struct linux_binprm *bprm,
24 struct tomoyo_page_dump *dump) 22 struct tomoyo_page_dump *dump)
25 { 23 {
26 static const int tomoyo_buffer_len = 4096 * 2; 24 static const int tomoyo_buffer_len = 4096 * 2;
27 char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS); 25 char *buffer = kzalloc(tomoyo_buffer_len, GFP_NOFS);
28 char *cp; 26 char *cp;
29 char *last_start; 27 char *last_start;
30 int len; 28 int len;
31 unsigned long pos = bprm->p; 29 unsigned long pos = bprm->p;
32 int offset = pos % PAGE_SIZE; 30 int offset = pos % PAGE_SIZE;
33 int argv_count = bprm->argc; 31 int argv_count = bprm->argc;
34 int envp_count = bprm->envc; 32 int envp_count = bprm->envc;
35 bool truncated = false; 33 bool truncated = false;
36 if (!buffer) 34 if (!buffer)
37 return NULL; 35 return NULL;
38 len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ "); 36 len = snprintf(buffer, tomoyo_buffer_len - 1, "argv[]={ ");
39 cp = buffer + len; 37 cp = buffer + len;
40 if (!argv_count) { 38 if (!argv_count) {
41 memmove(cp, "} envp[]={ ", 11); 39 memmove(cp, "} envp[]={ ", 11);
42 cp += 11; 40 cp += 11;
43 } 41 }
44 last_start = cp; 42 last_start = cp;
45 while (argv_count || envp_count) { 43 while (argv_count || envp_count) {
46 if (!tomoyo_dump_page(bprm, pos, dump)) 44 if (!tomoyo_dump_page(bprm, pos, dump))
47 goto out; 45 goto out;
48 pos += PAGE_SIZE - offset; 46 pos += PAGE_SIZE - offset;
49 /* Read. */ 47 /* Read. */
50 while (offset < PAGE_SIZE) { 48 while (offset < PAGE_SIZE) {
51 const char *kaddr = dump->data; 49 const char *kaddr = dump->data;
52 const unsigned char c = kaddr[offset++]; 50 const unsigned char c = kaddr[offset++];
53 if (cp == last_start) 51 if (cp == last_start)
54 *cp++ = '"'; 52 *cp++ = '"';
55 if (cp >= buffer + tomoyo_buffer_len - 32) { 53 if (cp >= buffer + tomoyo_buffer_len - 32) {
56 /* Reserve some room for "..." string. */ 54 /* Reserve some room for "..." string. */
57 truncated = true; 55 truncated = true;
58 } else if (c == '\\') { 56 } else if (c == '\\') {
59 *cp++ = '\\'; 57 *cp++ = '\\';
60 *cp++ = '\\'; 58 *cp++ = '\\';
61 } else if (c > ' ' && c < 127) { 59 } else if (c > ' ' && c < 127) {
62 *cp++ = c; 60 *cp++ = c;
63 } else if (!c) { 61 } else if (!c) {
64 *cp++ = '"'; 62 *cp++ = '"';
65 *cp++ = ' '; 63 *cp++ = ' ';
66 last_start = cp; 64 last_start = cp;
67 } else { 65 } else {
68 *cp++ = '\\'; 66 *cp++ = '\\';
69 *cp++ = (c >> 6) + '0'; 67 *cp++ = (c >> 6) + '0';
70 *cp++ = ((c >> 3) & 7) + '0'; 68 *cp++ = ((c >> 3) & 7) + '0';
71 *cp++ = (c & 7) + '0'; 69 *cp++ = (c & 7) + '0';
72 } 70 }
73 if (c) 71 if (c)
74 continue; 72 continue;
75 if (argv_count) { 73 if (argv_count) {
76 if (--argv_count == 0) { 74 if (--argv_count == 0) {
77 if (truncated) { 75 if (truncated) {
78 cp = last_start; 76 cp = last_start;
79 memmove(cp, "... ", 4); 77 memmove(cp, "... ", 4);
80 cp += 4; 78 cp += 4;
81 } 79 }
82 memmove(cp, "} envp[]={ ", 11); 80 memmove(cp, "} envp[]={ ", 11);
83 cp += 11; 81 cp += 11;
84 last_start = cp; 82 last_start = cp;
85 truncated = false; 83 truncated = false;
86 } 84 }
87 } else if (envp_count) { 85 } else if (envp_count) {
88 if (--envp_count == 0) { 86 if (--envp_count == 0) {
89 if (truncated) { 87 if (truncated) {
90 cp = last_start; 88 cp = last_start;
91 memmove(cp, "... ", 4); 89 memmove(cp, "... ", 4);
92 cp += 4; 90 cp += 4;
93 } 91 }
94 } 92 }
95 } 93 }
96 if (!argv_count && !envp_count) 94 if (!argv_count && !envp_count)
97 break; 95 break;
98 } 96 }
99 offset = 0; 97 offset = 0;
100 } 98 }
101 *cp++ = '}'; 99 *cp++ = '}';
102 *cp = '\0'; 100 *cp = '\0';
103 return buffer; 101 return buffer;
104 out: 102 out:
105 snprintf(buffer, tomoyo_buffer_len - 1, 103 snprintf(buffer, tomoyo_buffer_len - 1,
106 "argv[]={ ... } envp[]= { ... }"); 104 "argv[]={ ... } envp[]= { ... }");
107 return buffer; 105 return buffer;
108 } 106 }
109 107
110 /** 108 /**
111 * tomoyo_filetype - Get string representation of file type. 109 * tomoyo_filetype - Get string representation of file type.
112 * 110 *
113 * @mode: Mode value for stat(). 111 * @mode: Mode value for stat().
114 * 112 *
115 * Returns file type string. 113 * Returns file type string.
116 */ 114 */
117 static inline const char *tomoyo_filetype(const mode_t mode) 115 static inline const char *tomoyo_filetype(const mode_t mode)
118 { 116 {
119 switch (mode & S_IFMT) { 117 switch (mode & S_IFMT) {
120 case S_IFREG: 118 case S_IFREG:
121 case 0: 119 case 0:
122 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE]; 120 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FILE];
123 case S_IFDIR: 121 case S_IFDIR:
124 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY]; 122 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_DIRECTORY];
125 case S_IFLNK: 123 case S_IFLNK:
126 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK]; 124 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SYMLINK];
127 case S_IFIFO: 125 case S_IFIFO:
128 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO]; 126 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_FIFO];
129 case S_IFSOCK: 127 case S_IFSOCK:
130 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET]; 128 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_SOCKET];
131 case S_IFBLK: 129 case S_IFBLK:
132 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV]; 130 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_BLOCK_DEV];
133 case S_IFCHR: 131 case S_IFCHR:
134 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV]; 132 return tomoyo_condition_keyword[TOMOYO_TYPE_IS_CHAR_DEV];
135 } 133 }
136 return "unknown"; /* This should not happen. */ 134 return "unknown"; /* This should not happen. */
137 } 135 }
138 136
139 /** 137 /**
140 * tomoyo_print_header - Get header line of audit log. 138 * tomoyo_print_header - Get header line of audit log.
141 * 139 *
142 * @r: Pointer to "struct tomoyo_request_info". 140 * @r: Pointer to "struct tomoyo_request_info".
143 * 141 *
144 * Returns string representation. 142 * Returns string representation.
145 * 143 *
146 * This function uses kmalloc(), so caller must kfree() if this function 144 * This function uses kmalloc(), so caller must kfree() if this function
147 * didn't return NULL. 145 * didn't return NULL.
148 */ 146 */
149 static char *tomoyo_print_header(struct tomoyo_request_info *r) 147 static char *tomoyo_print_header(struct tomoyo_request_info *r)
150 { 148 {
151 struct tomoyo_time stamp; 149 struct tomoyo_time stamp;
152 const pid_t gpid = task_pid_nr(current); 150 const pid_t gpid = task_pid_nr(current);
153 struct tomoyo_obj_info *obj = r->obj; 151 struct tomoyo_obj_info *obj = r->obj;
154 static const int tomoyo_buffer_len = 4096; 152 static const int tomoyo_buffer_len = 4096;
155 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS); 153 char *buffer = kmalloc(tomoyo_buffer_len, GFP_NOFS);
156 int pos; 154 int pos;
157 u8 i; 155 u8 i;
158 if (!buffer) 156 if (!buffer)
159 return NULL; 157 return NULL;
160 { 158 {
161 struct timeval tv; 159 struct timeval tv;
162 do_gettimeofday(&tv); 160 do_gettimeofday(&tv);
163 tomoyo_convert_time(tv.tv_sec, &stamp); 161 tomoyo_convert_time(tv.tv_sec, &stamp);
164 } 162 }
165 pos = snprintf(buffer, tomoyo_buffer_len - 1, 163 pos = snprintf(buffer, tomoyo_buffer_len - 1,
166 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s " 164 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
167 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u " 165 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
168 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u " 166 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
169 "fsuid=%u fsgid=%u }", stamp.year, stamp.month, 167 "fsuid=%u fsgid=%u }", stamp.year, stamp.month,
170 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, 168 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
171 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid, 169 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
172 tomoyo_sys_getpid(), tomoyo_sys_getppid(), 170 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
173 current_uid(), current_gid(), current_euid(), 171 current_uid(), current_gid(), current_euid(),
174 current_egid(), current_suid(), current_sgid(), 172 current_egid(), current_suid(), current_sgid(),
175 current_fsuid(), current_fsgid()); 173 current_fsuid(), current_fsgid());
176 if (!obj) 174 if (!obj)
177 goto no_obj_info; 175 goto no_obj_info;
178 if (!obj->validate_done) { 176 if (!obj->validate_done) {
179 tomoyo_get_attributes(obj); 177 tomoyo_get_attributes(obj);
180 obj->validate_done = true; 178 obj->validate_done = true;
181 } 179 }
182 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { 180 for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) {
183 struct tomoyo_mini_stat *stat; 181 struct tomoyo_mini_stat *stat;
184 unsigned int dev; 182 unsigned int dev;
185 mode_t mode; 183 mode_t mode;
186 if (!obj->stat_valid[i]) 184 if (!obj->stat_valid[i])
187 continue; 185 continue;
188 stat = &obj->stat[i]; 186 stat = &obj->stat[i];
189 dev = stat->dev; 187 dev = stat->dev;
190 mode = stat->mode; 188 mode = stat->mode;
191 if (i & 1) { 189 if (i & 1) {
192 pos += snprintf(buffer + pos, 190 pos += snprintf(buffer + pos,
193 tomoyo_buffer_len - 1 - pos, 191 tomoyo_buffer_len - 1 - pos,
194 " path%u.parent={ uid=%u gid=%u " 192 " path%u.parent={ uid=%u gid=%u "
195 "ino=%lu perm=0%o }", (i >> 1) + 1, 193 "ino=%lu perm=0%o }", (i >> 1) + 1,
196 stat->uid, stat->gid, (unsigned long) 194 stat->uid, stat->gid, (unsigned long)
197 stat->ino, stat->mode & S_IALLUGO); 195 stat->ino, stat->mode & S_IALLUGO);
198 continue; 196 continue;
199 } 197 }
200 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, 198 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
201 " path%u={ uid=%u gid=%u ino=%lu major=%u" 199 " path%u={ uid=%u gid=%u ino=%lu major=%u"
202 " minor=%u perm=0%o type=%s", (i >> 1) + 1, 200 " minor=%u perm=0%o type=%s", (i >> 1) + 1,
203 stat->uid, stat->gid, (unsigned long) 201 stat->uid, stat->gid, (unsigned long)
204 stat->ino, MAJOR(dev), MINOR(dev), 202 stat->ino, MAJOR(dev), MINOR(dev),
205 mode & S_IALLUGO, tomoyo_filetype(mode)); 203 mode & S_IALLUGO, tomoyo_filetype(mode));
206 if (S_ISCHR(mode) || S_ISBLK(mode)) { 204 if (S_ISCHR(mode) || S_ISBLK(mode)) {
207 dev = stat->rdev; 205 dev = stat->rdev;
208 pos += snprintf(buffer + pos, 206 pos += snprintf(buffer + pos,
209 tomoyo_buffer_len - 1 - pos, 207 tomoyo_buffer_len - 1 - pos,
210 " dev_major=%u dev_minor=%u", 208 " dev_major=%u dev_minor=%u",
211 MAJOR(dev), MINOR(dev)); 209 MAJOR(dev), MINOR(dev));
212 } 210 }
213 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, 211 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
214 " }"); 212 " }");
215 } 213 }
216 no_obj_info: 214 no_obj_info:
217 if (pos < tomoyo_buffer_len - 1) 215 if (pos < tomoyo_buffer_len - 1)
218 return buffer; 216 return buffer;
219 kfree(buffer); 217 kfree(buffer);
220 return NULL; 218 return NULL;
221 } 219 }
222 220
223 /** 221 /**
224 * tomoyo_init_log - Allocate buffer for audit logs. 222 * tomoyo_init_log - Allocate buffer for audit logs.
225 * 223 *
226 * @r: Pointer to "struct tomoyo_request_info". 224 * @r: Pointer to "struct tomoyo_request_info".
227 * @len: Buffer size needed for @fmt and @args. 225 * @len: Buffer size needed for @fmt and @args.
228 * @fmt: The printf()'s format string. 226 * @fmt: The printf()'s format string.
229 * @args: va_list structure for @fmt. 227 * @args: va_list structure for @fmt.
230 * 228 *
231 * Returns pointer to allocated memory. 229 * Returns pointer to allocated memory.
232 * 230 *
233 * This function uses kzalloc(), so caller must kfree() if this function 231 * This function uses kzalloc(), so caller must kfree() if this function
234 * didn't return NULL. 232 * didn't return NULL.
235 */ 233 */
236 char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt, 234 char *tomoyo_init_log(struct tomoyo_request_info *r, int len, const char *fmt,
237 va_list args) 235 va_list args)
238 { 236 {
239 char *buf = NULL; 237 char *buf = NULL;
240 char *bprm_info = NULL; 238 char *bprm_info = NULL;
241 const char *header = NULL; 239 const char *header = NULL;
242 char *realpath = NULL; 240 char *realpath = NULL;
243 const char *symlink = NULL; 241 const char *symlink = NULL;
244 int pos; 242 int pos;
245 const char *domainname = r->domain->domainname->name; 243 const char *domainname = r->domain->domainname->name;
246 header = tomoyo_print_header(r); 244 header = tomoyo_print_header(r);
247 if (!header) 245 if (!header)
248 return NULL; 246 return NULL;
249 /* +10 is for '\n' etc. and '\0'. */ 247 /* +10 is for '\n' etc. and '\0'. */
250 len += strlen(domainname) + strlen(header) + 10; 248 len += strlen(domainname) + strlen(header) + 10;
251 if (r->ee) { 249 if (r->ee) {
252 struct file *file = r->ee->bprm->file; 250 struct file *file = r->ee->bprm->file;
253 realpath = tomoyo_realpath_from_path(&file->f_path); 251 realpath = tomoyo_realpath_from_path(&file->f_path);
254 bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump); 252 bprm_info = tomoyo_print_bprm(r->ee->bprm, &r->ee->dump);
255 if (!realpath || !bprm_info) 253 if (!realpath || !bprm_info)
256 goto out; 254 goto out;
257 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */ 255 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
258 len += strlen(realpath) + 80 + strlen(bprm_info); 256 len += strlen(realpath) + 80 + strlen(bprm_info);
259 } else if (r->obj && r->obj->symlink_target) { 257 } else if (r->obj && r->obj->symlink_target) {
260 symlink = r->obj->symlink_target->name; 258 symlink = r->obj->symlink_target->name;
261 /* +18 is for " symlink.target=\"%s\"" */ 259 /* +18 is for " symlink.target=\"%s\"" */
262 len += 18 + strlen(symlink); 260 len += 18 + strlen(symlink);
263 } 261 }
264 len = tomoyo_round2(len); 262 len = tomoyo_round2(len);
265 buf = kzalloc(len, GFP_NOFS); 263 buf = kzalloc(len, GFP_NOFS);
266 if (!buf) 264 if (!buf)
267 goto out; 265 goto out;
268 len--; 266 len--;
269 pos = snprintf(buf, len, "%s", header); 267 pos = snprintf(buf, len, "%s", header);
270 if (realpath) { 268 if (realpath) {
271 struct linux_binprm *bprm = r->ee->bprm; 269 struct linux_binprm *bprm = r->ee->bprm;
272 pos += snprintf(buf + pos, len - pos, 270 pos += snprintf(buf + pos, len - pos,
273 " exec={ realpath=\"%s\" argc=%d envc=%d %s }", 271 " exec={ realpath=\"%s\" argc=%d envc=%d %s }",
274 realpath, bprm->argc, bprm->envc, bprm_info); 272 realpath, bprm->argc, bprm->envc, bprm_info);
275 } else if (symlink) 273 } else if (symlink)
276 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"", 274 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
277 symlink); 275 symlink);
278 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); 276 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
279 vsnprintf(buf + pos, len - pos, fmt, args); 277 vsnprintf(buf + pos, len - pos, fmt, args);
280 out: 278 out:
281 kfree(realpath); 279 kfree(realpath);
282 kfree(bprm_info); 280 kfree(bprm_info);
283 kfree(header); 281 kfree(header);
284 return buf; 282 return buf;
285 } 283 }
286 284
287 /* Wait queue for /sys/kernel/security/tomoyo/audit. */ 285 /* Wait queue for /sys/kernel/security/tomoyo/audit. */
288 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait); 286 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_log_wait);
289 287
290 /* Structure for audit log. */ 288 /* Structure for audit log. */
291 struct tomoyo_log { 289 struct tomoyo_log {
292 struct list_head list; 290 struct list_head list;
293 char *log; 291 char *log;
294 int size; 292 int size;
295 }; 293 };
296 294
297 /* The list for "struct tomoyo_log". */ 295 /* The list for "struct tomoyo_log". */
298 static LIST_HEAD(tomoyo_log); 296 static LIST_HEAD(tomoyo_log);
299 297
300 /* Lock for "struct list_head tomoyo_log". */ 298 /* Lock for "struct list_head tomoyo_log". */
301 static DEFINE_SPINLOCK(tomoyo_log_lock); 299 static DEFINE_SPINLOCK(tomoyo_log_lock);
302 300
303 /* Length of "stuct list_head tomoyo_log". */ 301 /* Length of "stuct list_head tomoyo_log". */
304 static unsigned int tomoyo_log_count; 302 static unsigned int tomoyo_log_count;
305 303
306 /** 304 /**
307 * tomoyo_get_audit - Get audit mode. 305 * tomoyo_get_audit - Get audit mode.
308 * 306 *
309 * @ns: Pointer to "struct tomoyo_policy_namespace". 307 * @ns: Pointer to "struct tomoyo_policy_namespace".
310 * @profile: Profile number. 308 * @profile: Profile number.
311 * @index: Index number of functionality. 309 * @index: Index number of functionality.
312 * @is_granted: True if granted log, false otherwise. 310 * @is_granted: True if granted log, false otherwise.
313 * 311 *
314 * Returns true if this request should be audited, false otherwise. 312 * Returns true if this request should be audited, false otherwise.
315 */ 313 */
316 static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns, 314 static bool tomoyo_get_audit(const struct tomoyo_policy_namespace *ns,
317 const u8 profile, const u8 index, 315 const u8 profile, const u8 index,
318 const bool is_granted) 316 const bool is_granted)
319 { 317 {
320 u8 mode; 318 u8 mode;
321 const u8 category = tomoyo_index2category[index] + 319 const u8 category = tomoyo_index2category[index] +
322 TOMOYO_MAX_MAC_INDEX; 320 TOMOYO_MAX_MAC_INDEX;
323 struct tomoyo_profile *p; 321 struct tomoyo_profile *p;
324 if (!tomoyo_policy_loaded) 322 if (!tomoyo_policy_loaded)
325 return false; 323 return false;
326 p = tomoyo_profile(ns, profile); 324 p = tomoyo_profile(ns, profile);
327 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG]) 325 if (tomoyo_log_count >= p->pref[TOMOYO_PREF_MAX_AUDIT_LOG])
328 return false; 326 return false;
329 mode = p->config[index]; 327 mode = p->config[index];
330 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 328 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
331 mode = p->config[category]; 329 mode = p->config[category];
332 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 330 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
333 mode = p->default_config; 331 mode = p->default_config;
334 if (is_granted) 332 if (is_granted)
335 return mode & TOMOYO_CONFIG_WANT_GRANT_LOG; 333 return mode & TOMOYO_CONFIG_WANT_GRANT_LOG;
336 return mode & TOMOYO_CONFIG_WANT_REJECT_LOG; 334 return mode & TOMOYO_CONFIG_WANT_REJECT_LOG;
337 } 335 }
338 336
339 /** 337 /**
340 * tomoyo_write_log2 - Write an audit log. 338 * tomoyo_write_log2 - Write an audit log.
341 * 339 *
342 * @r: Pointer to "struct tomoyo_request_info". 340 * @r: Pointer to "struct tomoyo_request_info".
343 * @len: Buffer size needed for @fmt and @args. 341 * @len: Buffer size needed for @fmt and @args.
344 * @fmt: The printf()'s format string. 342 * @fmt: The printf()'s format string.
345 * @args: va_list structure for @fmt. 343 * @args: va_list structure for @fmt.
346 * 344 *
347 * Returns nothing. 345 * Returns nothing.
348 */ 346 */
349 void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, 347 void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt,
350 va_list args) 348 va_list args)
351 { 349 {
352 char *buf; 350 char *buf;
353 struct tomoyo_log *entry; 351 struct tomoyo_log *entry;
354 bool quota_exceeded = false; 352 bool quota_exceeded = false;
355 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted)) 353 if (!tomoyo_get_audit(r->domain->ns, r->profile, r->type, r->granted))
356 goto out; 354 goto out;
357 buf = tomoyo_init_log(r, len, fmt, args); 355 buf = tomoyo_init_log(r, len, fmt, args);
358 if (!buf) 356 if (!buf)
359 goto out; 357 goto out;
360 entry = kzalloc(sizeof(*entry), GFP_NOFS); 358 entry = kzalloc(sizeof(*entry), GFP_NOFS);
361 if (!entry) { 359 if (!entry) {
362 kfree(buf); 360 kfree(buf);
363 goto out; 361 goto out;
364 } 362 }
365 entry->log = buf; 363 entry->log = buf;
366 len = tomoyo_round2(strlen(buf) + 1); 364 len = tomoyo_round2(strlen(buf) + 1);
367 /* 365 /*
368 * The entry->size is used for memory quota checks. 366 * The entry->size is used for memory quota checks.
369 * Don't go beyond strlen(entry->log). 367 * Don't go beyond strlen(entry->log).
370 */ 368 */
371 entry->size = len + tomoyo_round2(sizeof(*entry)); 369 entry->size = len + tomoyo_round2(sizeof(*entry));
372 spin_lock(&tomoyo_log_lock); 370 spin_lock(&tomoyo_log_lock);
373 if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] && 371 if (tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT] &&
374 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >= 372 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] + entry->size >=
375 tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) { 373 tomoyo_memory_quota[TOMOYO_MEMORY_AUDIT]) {
376 quota_exceeded = true; 374 quota_exceeded = true;
377 } else { 375 } else {
378 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size; 376 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] += entry->size;
379 list_add_tail(&entry->list, &tomoyo_log); 377 list_add_tail(&entry->list, &tomoyo_log);
380 tomoyo_log_count++; 378 tomoyo_log_count++;
381 } 379 }
382 spin_unlock(&tomoyo_log_lock); 380 spin_unlock(&tomoyo_log_lock);
383 if (quota_exceeded) { 381 if (quota_exceeded) {
384 kfree(buf); 382 kfree(buf);
385 kfree(entry); 383 kfree(entry);
386 goto out; 384 goto out;
387 } 385 }
388 wake_up(&tomoyo_log_wait); 386 wake_up(&tomoyo_log_wait);
389 out: 387 out:
390 return; 388 return;
391 } 389 }
392 390
393 /** 391 /**
394 * tomoyo_write_log - Write an audit log. 392 * tomoyo_write_log - Write an audit log.
395 * 393 *
396 * @r: Pointer to "struct tomoyo_request_info". 394 * @r: Pointer to "struct tomoyo_request_info".
397 * @fmt: The printf()'s format string, followed by parameters. 395 * @fmt: The printf()'s format string, followed by parameters.
398 * 396 *
399 * Returns nothing. 397 * Returns nothing.
400 */ 398 */
401 void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...) 399 void tomoyo_write_log(struct tomoyo_request_info *r, const char *fmt, ...)
402 { 400 {
403 va_list args; 401 va_list args;
404 int len; 402 int len;
405 va_start(args, fmt); 403 va_start(args, fmt);
406 len = vsnprintf((char *) &len, 1, fmt, args) + 1; 404 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
407 va_end(args); 405 va_end(args);
408 va_start(args, fmt); 406 va_start(args, fmt);
409 tomoyo_write_log2(r, len, fmt, args); 407 tomoyo_write_log2(r, len, fmt, args);
410 va_end(args); 408 va_end(args);
411 } 409 }
412 410
413 /** 411 /**
414 * tomoyo_read_log - Read an audit log. 412 * tomoyo_read_log - Read an audit log.
415 * 413 *
416 * @head: Pointer to "struct tomoyo_io_buffer". 414 * @head: Pointer to "struct tomoyo_io_buffer".
417 * 415 *
418 * Returns nothing. 416 * Returns nothing.
419 */ 417 */
420 void tomoyo_read_log(struct tomoyo_io_buffer *head) 418 void tomoyo_read_log(struct tomoyo_io_buffer *head)
421 { 419 {
422 struct tomoyo_log *ptr = NULL; 420 struct tomoyo_log *ptr = NULL;
423 if (head->r.w_pos) 421 if (head->r.w_pos)
424 return; 422 return;
425 kfree(head->read_buf); 423 kfree(head->read_buf);
426 head->read_buf = NULL; 424 head->read_buf = NULL;
427 spin_lock(&tomoyo_log_lock); 425 spin_lock(&tomoyo_log_lock);
428 if (!list_empty(&tomoyo_log)) { 426 if (!list_empty(&tomoyo_log)) {
429 ptr = list_entry(tomoyo_log.next, typeof(*ptr), list); 427 ptr = list_entry(tomoyo_log.next, typeof(*ptr), list);
430 list_del(&ptr->list); 428 list_del(&ptr->list);
431 tomoyo_log_count--; 429 tomoyo_log_count--;
432 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size; 430 tomoyo_memory_used[TOMOYO_MEMORY_AUDIT] -= ptr->size;
433 } 431 }
434 spin_unlock(&tomoyo_log_lock); 432 spin_unlock(&tomoyo_log_lock);
435 if (ptr) { 433 if (ptr) {
436 head->read_buf = ptr->log; 434 head->read_buf = ptr->log;
437 head->r.w[head->r.w_pos++] = head->read_buf; 435 head->r.w[head->r.w_pos++] = head->read_buf;
438 kfree(ptr); 436 kfree(ptr);
439 } 437 }
440 } 438 }
441 439
442 /** 440 /**
443 * tomoyo_poll_log - Wait for an audit log. 441 * tomoyo_poll_log - Wait for an audit log.
444 * 442 *
445 * @file: Pointer to "struct file". 443 * @file: Pointer to "struct file".
446 * @wait: Pointer to "poll_table". 444 * @wait: Pointer to "poll_table".
447 * 445 *
448 * Returns POLLIN | POLLRDNORM when ready to read an audit log. 446 * Returns POLLIN | POLLRDNORM when ready to read an audit log.
449 */ 447 */
450 int tomoyo_poll_log(struct file *file, poll_table *wait) 448 int tomoyo_poll_log(struct file *file, poll_table *wait)
451 { 449 {
452 if (tomoyo_log_count) 450 if (tomoyo_log_count)
453 return POLLIN | POLLRDNORM; 451 return POLLIN | POLLRDNORM;
454 poll_wait(file, &tomoyo_log_wait, wait); 452 poll_wait(file, &tomoyo_log_wait, wait);
455 if (tomoyo_log_count) 453 if (tomoyo_log_count)
456 return POLLIN | POLLRDNORM; 454 return POLLIN | POLLRDNORM;
457 return 0; 455 return 0;
458 } 456 }
459 457
security/tomoyo/common.c
1 /* 1 /*
2 * security/tomoyo/common.c 2 * security/tomoyo/common.c
3 * 3 *
4 * Common functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/uaccess.h> 7 #include <linux/uaccess.h>
10 #include <linux/slab.h> 8 #include <linux/slab.h>
11 #include <linux/security.h> 9 #include <linux/security.h>
12 #include "common.h" 10 #include "common.h"
13 11
14 /* String table for operation mode. */ 12 /* String table for operation mode. */
15 const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = { 13 const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
16 [TOMOYO_CONFIG_DISABLED] = "disabled", 14 [TOMOYO_CONFIG_DISABLED] = "disabled",
17 [TOMOYO_CONFIG_LEARNING] = "learning", 15 [TOMOYO_CONFIG_LEARNING] = "learning",
18 [TOMOYO_CONFIG_PERMISSIVE] = "permissive", 16 [TOMOYO_CONFIG_PERMISSIVE] = "permissive",
19 [TOMOYO_CONFIG_ENFORCING] = "enforcing" 17 [TOMOYO_CONFIG_ENFORCING] = "enforcing"
20 }; 18 };
21 19
22 /* String table for /sys/kernel/security/tomoyo/profile */ 20 /* String table for /sys/kernel/security/tomoyo/profile */
23 const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX 21 const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
24 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 22 + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
25 [TOMOYO_MAC_FILE_EXECUTE] = "execute", 23 [TOMOYO_MAC_FILE_EXECUTE] = "execute",
26 [TOMOYO_MAC_FILE_OPEN] = "open", 24 [TOMOYO_MAC_FILE_OPEN] = "open",
27 [TOMOYO_MAC_FILE_CREATE] = "create", 25 [TOMOYO_MAC_FILE_CREATE] = "create",
28 [TOMOYO_MAC_FILE_UNLINK] = "unlink", 26 [TOMOYO_MAC_FILE_UNLINK] = "unlink",
29 [TOMOYO_MAC_FILE_GETATTR] = "getattr", 27 [TOMOYO_MAC_FILE_GETATTR] = "getattr",
30 [TOMOYO_MAC_FILE_MKDIR] = "mkdir", 28 [TOMOYO_MAC_FILE_MKDIR] = "mkdir",
31 [TOMOYO_MAC_FILE_RMDIR] = "rmdir", 29 [TOMOYO_MAC_FILE_RMDIR] = "rmdir",
32 [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo", 30 [TOMOYO_MAC_FILE_MKFIFO] = "mkfifo",
33 [TOMOYO_MAC_FILE_MKSOCK] = "mksock", 31 [TOMOYO_MAC_FILE_MKSOCK] = "mksock",
34 [TOMOYO_MAC_FILE_TRUNCATE] = "truncate", 32 [TOMOYO_MAC_FILE_TRUNCATE] = "truncate",
35 [TOMOYO_MAC_FILE_SYMLINK] = "symlink", 33 [TOMOYO_MAC_FILE_SYMLINK] = "symlink",
36 [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock", 34 [TOMOYO_MAC_FILE_MKBLOCK] = "mkblock",
37 [TOMOYO_MAC_FILE_MKCHAR] = "mkchar", 35 [TOMOYO_MAC_FILE_MKCHAR] = "mkchar",
38 [TOMOYO_MAC_FILE_LINK] = "link", 36 [TOMOYO_MAC_FILE_LINK] = "link",
39 [TOMOYO_MAC_FILE_RENAME] = "rename", 37 [TOMOYO_MAC_FILE_RENAME] = "rename",
40 [TOMOYO_MAC_FILE_CHMOD] = "chmod", 38 [TOMOYO_MAC_FILE_CHMOD] = "chmod",
41 [TOMOYO_MAC_FILE_CHOWN] = "chown", 39 [TOMOYO_MAC_FILE_CHOWN] = "chown",
42 [TOMOYO_MAC_FILE_CHGRP] = "chgrp", 40 [TOMOYO_MAC_FILE_CHGRP] = "chgrp",
43 [TOMOYO_MAC_FILE_IOCTL] = "ioctl", 41 [TOMOYO_MAC_FILE_IOCTL] = "ioctl",
44 [TOMOYO_MAC_FILE_CHROOT] = "chroot", 42 [TOMOYO_MAC_FILE_CHROOT] = "chroot",
45 [TOMOYO_MAC_FILE_MOUNT] = "mount", 43 [TOMOYO_MAC_FILE_MOUNT] = "mount",
46 [TOMOYO_MAC_FILE_UMOUNT] = "unmount", 44 [TOMOYO_MAC_FILE_UMOUNT] = "unmount",
47 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root", 45 [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
48 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file", 46 [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
49 }; 47 };
50 48
51 /* String table for conditions. */ 49 /* String table for conditions. */
52 const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = { 50 const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
53 [TOMOYO_TASK_UID] = "task.uid", 51 [TOMOYO_TASK_UID] = "task.uid",
54 [TOMOYO_TASK_EUID] = "task.euid", 52 [TOMOYO_TASK_EUID] = "task.euid",
55 [TOMOYO_TASK_SUID] = "task.suid", 53 [TOMOYO_TASK_SUID] = "task.suid",
56 [TOMOYO_TASK_FSUID] = "task.fsuid", 54 [TOMOYO_TASK_FSUID] = "task.fsuid",
57 [TOMOYO_TASK_GID] = "task.gid", 55 [TOMOYO_TASK_GID] = "task.gid",
58 [TOMOYO_TASK_EGID] = "task.egid", 56 [TOMOYO_TASK_EGID] = "task.egid",
59 [TOMOYO_TASK_SGID] = "task.sgid", 57 [TOMOYO_TASK_SGID] = "task.sgid",
60 [TOMOYO_TASK_FSGID] = "task.fsgid", 58 [TOMOYO_TASK_FSGID] = "task.fsgid",
61 [TOMOYO_TASK_PID] = "task.pid", 59 [TOMOYO_TASK_PID] = "task.pid",
62 [TOMOYO_TASK_PPID] = "task.ppid", 60 [TOMOYO_TASK_PPID] = "task.ppid",
63 [TOMOYO_EXEC_ARGC] = "exec.argc", 61 [TOMOYO_EXEC_ARGC] = "exec.argc",
64 [TOMOYO_EXEC_ENVC] = "exec.envc", 62 [TOMOYO_EXEC_ENVC] = "exec.envc",
65 [TOMOYO_TYPE_IS_SOCKET] = "socket", 63 [TOMOYO_TYPE_IS_SOCKET] = "socket",
66 [TOMOYO_TYPE_IS_SYMLINK] = "symlink", 64 [TOMOYO_TYPE_IS_SYMLINK] = "symlink",
67 [TOMOYO_TYPE_IS_FILE] = "file", 65 [TOMOYO_TYPE_IS_FILE] = "file",
68 [TOMOYO_TYPE_IS_BLOCK_DEV] = "block", 66 [TOMOYO_TYPE_IS_BLOCK_DEV] = "block",
69 [TOMOYO_TYPE_IS_DIRECTORY] = "directory", 67 [TOMOYO_TYPE_IS_DIRECTORY] = "directory",
70 [TOMOYO_TYPE_IS_CHAR_DEV] = "char", 68 [TOMOYO_TYPE_IS_CHAR_DEV] = "char",
71 [TOMOYO_TYPE_IS_FIFO] = "fifo", 69 [TOMOYO_TYPE_IS_FIFO] = "fifo",
72 [TOMOYO_MODE_SETUID] = "setuid", 70 [TOMOYO_MODE_SETUID] = "setuid",
73 [TOMOYO_MODE_SETGID] = "setgid", 71 [TOMOYO_MODE_SETGID] = "setgid",
74 [TOMOYO_MODE_STICKY] = "sticky", 72 [TOMOYO_MODE_STICKY] = "sticky",
75 [TOMOYO_MODE_OWNER_READ] = "owner_read", 73 [TOMOYO_MODE_OWNER_READ] = "owner_read",
76 [TOMOYO_MODE_OWNER_WRITE] = "owner_write", 74 [TOMOYO_MODE_OWNER_WRITE] = "owner_write",
77 [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute", 75 [TOMOYO_MODE_OWNER_EXECUTE] = "owner_execute",
78 [TOMOYO_MODE_GROUP_READ] = "group_read", 76 [TOMOYO_MODE_GROUP_READ] = "group_read",
79 [TOMOYO_MODE_GROUP_WRITE] = "group_write", 77 [TOMOYO_MODE_GROUP_WRITE] = "group_write",
80 [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute", 78 [TOMOYO_MODE_GROUP_EXECUTE] = "group_execute",
81 [TOMOYO_MODE_OTHERS_READ] = "others_read", 79 [TOMOYO_MODE_OTHERS_READ] = "others_read",
82 [TOMOYO_MODE_OTHERS_WRITE] = "others_write", 80 [TOMOYO_MODE_OTHERS_WRITE] = "others_write",
83 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute", 81 [TOMOYO_MODE_OTHERS_EXECUTE] = "others_execute",
84 [TOMOYO_EXEC_REALPATH] = "exec.realpath", 82 [TOMOYO_EXEC_REALPATH] = "exec.realpath",
85 [TOMOYO_SYMLINK_TARGET] = "symlink.target", 83 [TOMOYO_SYMLINK_TARGET] = "symlink.target",
86 [TOMOYO_PATH1_UID] = "path1.uid", 84 [TOMOYO_PATH1_UID] = "path1.uid",
87 [TOMOYO_PATH1_GID] = "path1.gid", 85 [TOMOYO_PATH1_GID] = "path1.gid",
88 [TOMOYO_PATH1_INO] = "path1.ino", 86 [TOMOYO_PATH1_INO] = "path1.ino",
89 [TOMOYO_PATH1_MAJOR] = "path1.major", 87 [TOMOYO_PATH1_MAJOR] = "path1.major",
90 [TOMOYO_PATH1_MINOR] = "path1.minor", 88 [TOMOYO_PATH1_MINOR] = "path1.minor",
91 [TOMOYO_PATH1_PERM] = "path1.perm", 89 [TOMOYO_PATH1_PERM] = "path1.perm",
92 [TOMOYO_PATH1_TYPE] = "path1.type", 90 [TOMOYO_PATH1_TYPE] = "path1.type",
93 [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major", 91 [TOMOYO_PATH1_DEV_MAJOR] = "path1.dev_major",
94 [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor", 92 [TOMOYO_PATH1_DEV_MINOR] = "path1.dev_minor",
95 [TOMOYO_PATH2_UID] = "path2.uid", 93 [TOMOYO_PATH2_UID] = "path2.uid",
96 [TOMOYO_PATH2_GID] = "path2.gid", 94 [TOMOYO_PATH2_GID] = "path2.gid",
97 [TOMOYO_PATH2_INO] = "path2.ino", 95 [TOMOYO_PATH2_INO] = "path2.ino",
98 [TOMOYO_PATH2_MAJOR] = "path2.major", 96 [TOMOYO_PATH2_MAJOR] = "path2.major",
99 [TOMOYO_PATH2_MINOR] = "path2.minor", 97 [TOMOYO_PATH2_MINOR] = "path2.minor",
100 [TOMOYO_PATH2_PERM] = "path2.perm", 98 [TOMOYO_PATH2_PERM] = "path2.perm",
101 [TOMOYO_PATH2_TYPE] = "path2.type", 99 [TOMOYO_PATH2_TYPE] = "path2.type",
102 [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major", 100 [TOMOYO_PATH2_DEV_MAJOR] = "path2.dev_major",
103 [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor", 101 [TOMOYO_PATH2_DEV_MINOR] = "path2.dev_minor",
104 [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid", 102 [TOMOYO_PATH1_PARENT_UID] = "path1.parent.uid",
105 [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid", 103 [TOMOYO_PATH1_PARENT_GID] = "path1.parent.gid",
106 [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino", 104 [TOMOYO_PATH1_PARENT_INO] = "path1.parent.ino",
107 [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm", 105 [TOMOYO_PATH1_PARENT_PERM] = "path1.parent.perm",
108 [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid", 106 [TOMOYO_PATH2_PARENT_UID] = "path2.parent.uid",
109 [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid", 107 [TOMOYO_PATH2_PARENT_GID] = "path2.parent.gid",
110 [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino", 108 [TOMOYO_PATH2_PARENT_INO] = "path2.parent.ino",
111 [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm", 109 [TOMOYO_PATH2_PARENT_PERM] = "path2.parent.perm",
112 }; 110 };
113 111
114 /* String table for PREFERENCE keyword. */ 112 /* String table for PREFERENCE keyword. */
115 static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = { 113 static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
116 [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log", 114 [TOMOYO_PREF_MAX_AUDIT_LOG] = "max_audit_log",
117 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry", 115 [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
118 }; 116 };
119 117
120 /* String table for path operation. */ 118 /* String table for path operation. */
121 const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = { 119 const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
122 [TOMOYO_TYPE_EXECUTE] = "execute", 120 [TOMOYO_TYPE_EXECUTE] = "execute",
123 [TOMOYO_TYPE_READ] = "read", 121 [TOMOYO_TYPE_READ] = "read",
124 [TOMOYO_TYPE_WRITE] = "write", 122 [TOMOYO_TYPE_WRITE] = "write",
125 [TOMOYO_TYPE_APPEND] = "append", 123 [TOMOYO_TYPE_APPEND] = "append",
126 [TOMOYO_TYPE_UNLINK] = "unlink", 124 [TOMOYO_TYPE_UNLINK] = "unlink",
127 [TOMOYO_TYPE_GETATTR] = "getattr", 125 [TOMOYO_TYPE_GETATTR] = "getattr",
128 [TOMOYO_TYPE_RMDIR] = "rmdir", 126 [TOMOYO_TYPE_RMDIR] = "rmdir",
129 [TOMOYO_TYPE_TRUNCATE] = "truncate", 127 [TOMOYO_TYPE_TRUNCATE] = "truncate",
130 [TOMOYO_TYPE_SYMLINK] = "symlink", 128 [TOMOYO_TYPE_SYMLINK] = "symlink",
131 [TOMOYO_TYPE_CHROOT] = "chroot", 129 [TOMOYO_TYPE_CHROOT] = "chroot",
132 [TOMOYO_TYPE_UMOUNT] = "unmount", 130 [TOMOYO_TYPE_UMOUNT] = "unmount",
133 }; 131 };
134 132
135 /* String table for categories. */ 133 /* String table for categories. */
136 static const char * const tomoyo_category_keywords 134 static const char * const tomoyo_category_keywords
137 [TOMOYO_MAX_MAC_CATEGORY_INDEX] = { 135 [TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
138 [TOMOYO_MAC_CATEGORY_FILE] = "file", 136 [TOMOYO_MAC_CATEGORY_FILE] = "file",
139 }; 137 };
140 138
141 /* Permit policy management by non-root user? */ 139 /* Permit policy management by non-root user? */
142 static bool tomoyo_manage_by_non_root; 140 static bool tomoyo_manage_by_non_root;
143 141
144 /* Utility functions. */ 142 /* Utility functions. */
145 143
146 /** 144 /**
147 * tomoyo_yesno - Return "yes" or "no". 145 * tomoyo_yesno - Return "yes" or "no".
148 * 146 *
149 * @value: Bool value. 147 * @value: Bool value.
150 */ 148 */
151 const char *tomoyo_yesno(const unsigned int value) 149 const char *tomoyo_yesno(const unsigned int value)
152 { 150 {
153 return value ? "yes" : "no"; 151 return value ? "yes" : "no";
154 } 152 }
155 153
156 /** 154 /**
157 * tomoyo_addprintf - strncat()-like-snprintf(). 155 * tomoyo_addprintf - strncat()-like-snprintf().
158 * 156 *
159 * @buffer: Buffer to write to. Must be '\0'-terminated. 157 * @buffer: Buffer to write to. Must be '\0'-terminated.
160 * @len: Size of @buffer. 158 * @len: Size of @buffer.
161 * @fmt: The printf()'s format string, followed by parameters. 159 * @fmt: The printf()'s format string, followed by parameters.
162 * 160 *
163 * Returns nothing. 161 * Returns nothing.
164 */ 162 */
165 static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...) 163 static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
166 { 164 {
167 va_list args; 165 va_list args;
168 const int pos = strlen(buffer); 166 const int pos = strlen(buffer);
169 va_start(args, fmt); 167 va_start(args, fmt);
170 vsnprintf(buffer + pos, len - pos - 1, fmt, args); 168 vsnprintf(buffer + pos, len - pos - 1, fmt, args);
171 va_end(args); 169 va_end(args);
172 } 170 }
173 171
174 /** 172 /**
175 * tomoyo_flush - Flush queued string to userspace's buffer. 173 * tomoyo_flush - Flush queued string to userspace's buffer.
176 * 174 *
177 * @head: Pointer to "struct tomoyo_io_buffer". 175 * @head: Pointer to "struct tomoyo_io_buffer".
178 * 176 *
179 * Returns true if all data was flushed, false otherwise. 177 * Returns true if all data was flushed, false otherwise.
180 */ 178 */
181 static bool tomoyo_flush(struct tomoyo_io_buffer *head) 179 static bool tomoyo_flush(struct tomoyo_io_buffer *head)
182 { 180 {
183 while (head->r.w_pos) { 181 while (head->r.w_pos) {
184 const char *w = head->r.w[0]; 182 const char *w = head->r.w[0];
185 size_t len = strlen(w); 183 size_t len = strlen(w);
186 if (len) { 184 if (len) {
187 if (len > head->read_user_buf_avail) 185 if (len > head->read_user_buf_avail)
188 len = head->read_user_buf_avail; 186 len = head->read_user_buf_avail;
189 if (!len) 187 if (!len)
190 return false; 188 return false;
191 if (copy_to_user(head->read_user_buf, w, len)) 189 if (copy_to_user(head->read_user_buf, w, len))
192 return false; 190 return false;
193 head->read_user_buf_avail -= len; 191 head->read_user_buf_avail -= len;
194 head->read_user_buf += len; 192 head->read_user_buf += len;
195 w += len; 193 w += len;
196 } 194 }
197 head->r.w[0] = w; 195 head->r.w[0] = w;
198 if (*w) 196 if (*w)
199 return false; 197 return false;
200 /* Add '\0' for audit logs and query. */ 198 /* Add '\0' for audit logs and query. */
201 if (head->poll) { 199 if (head->poll) {
202 if (!head->read_user_buf_avail || 200 if (!head->read_user_buf_avail ||
203 copy_to_user(head->read_user_buf, "", 1)) 201 copy_to_user(head->read_user_buf, "", 1))
204 return false; 202 return false;
205 head->read_user_buf_avail--; 203 head->read_user_buf_avail--;
206 head->read_user_buf++; 204 head->read_user_buf++;
207 } 205 }
208 head->r.w_pos--; 206 head->r.w_pos--;
209 for (len = 0; len < head->r.w_pos; len++) 207 for (len = 0; len < head->r.w_pos; len++)
210 head->r.w[len] = head->r.w[len + 1]; 208 head->r.w[len] = head->r.w[len + 1];
211 } 209 }
212 head->r.avail = 0; 210 head->r.avail = 0;
213 return true; 211 return true;
214 } 212 }
215 213
216 /** 214 /**
217 * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure. 215 * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure.
218 * 216 *
219 * @head: Pointer to "struct tomoyo_io_buffer". 217 * @head: Pointer to "struct tomoyo_io_buffer".
220 * @string: String to print. 218 * @string: String to print.
221 * 219 *
222 * Note that @string has to be kept valid until @head is kfree()d. 220 * Note that @string has to be kept valid until @head is kfree()d.
223 * This means that char[] allocated on stack memory cannot be passed to 221 * This means that char[] allocated on stack memory cannot be passed to
224 * this function. Use tomoyo_io_printf() for char[] allocated on stack memory. 222 * this function. Use tomoyo_io_printf() for char[] allocated on stack memory.
225 */ 223 */
226 static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string) 224 static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
227 { 225 {
228 if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) { 226 if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) {
229 head->r.w[head->r.w_pos++] = string; 227 head->r.w[head->r.w_pos++] = string;
230 tomoyo_flush(head); 228 tomoyo_flush(head);
231 } else 229 } else
232 WARN_ON(1); 230 WARN_ON(1);
233 } 231 }
234 232
235 /** 233 /**
236 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. 234 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
237 * 235 *
238 * @head: Pointer to "struct tomoyo_io_buffer". 236 * @head: Pointer to "struct tomoyo_io_buffer".
239 * @fmt: The printf()'s format string, followed by parameters. 237 * @fmt: The printf()'s format string, followed by parameters.
240 */ 238 */
241 void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 239 void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
242 { 240 {
243 va_list args; 241 va_list args;
244 size_t len; 242 size_t len;
245 size_t pos = head->r.avail; 243 size_t pos = head->r.avail;
246 int size = head->readbuf_size - pos; 244 int size = head->readbuf_size - pos;
247 if (size <= 0) 245 if (size <= 0)
248 return; 246 return;
249 va_start(args, fmt); 247 va_start(args, fmt);
250 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; 248 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
251 va_end(args); 249 va_end(args);
252 if (pos + len >= head->readbuf_size) { 250 if (pos + len >= head->readbuf_size) {
253 WARN_ON(1); 251 WARN_ON(1);
254 return; 252 return;
255 } 253 }
256 head->r.avail += len; 254 head->r.avail += len;
257 tomoyo_set_string(head, head->read_buf + pos); 255 tomoyo_set_string(head, head->read_buf + pos);
258 } 256 }
259 257
260 /** 258 /**
261 * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure. 259 * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure.
262 * 260 *
263 * @head: Pointer to "struct tomoyo_io_buffer". 261 * @head: Pointer to "struct tomoyo_io_buffer".
264 * 262 *
265 * Returns nothing. 263 * Returns nothing.
266 */ 264 */
267 static void tomoyo_set_space(struct tomoyo_io_buffer *head) 265 static void tomoyo_set_space(struct tomoyo_io_buffer *head)
268 { 266 {
269 tomoyo_set_string(head, " "); 267 tomoyo_set_string(head, " ");
270 } 268 }
271 269
272 /** 270 /**
273 * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure. 271 * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure.
274 * 272 *
275 * @head: Pointer to "struct tomoyo_io_buffer". 273 * @head: Pointer to "struct tomoyo_io_buffer".
276 * 274 *
277 * Returns nothing. 275 * Returns nothing.
278 */ 276 */
279 static bool tomoyo_set_lf(struct tomoyo_io_buffer *head) 277 static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
280 { 278 {
281 tomoyo_set_string(head, "\n"); 279 tomoyo_set_string(head, "\n");
282 return !head->r.w_pos; 280 return !head->r.w_pos;
283 } 281 }
284 282
285 /** 283 /**
286 * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure. 284 * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure.
287 * 285 *
288 * @head: Pointer to "struct tomoyo_io_buffer". 286 * @head: Pointer to "struct tomoyo_io_buffer".
289 * 287 *
290 * Returns nothing. 288 * Returns nothing.
291 */ 289 */
292 static void tomoyo_set_slash(struct tomoyo_io_buffer *head) 290 static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
293 { 291 {
294 tomoyo_set_string(head, "/"); 292 tomoyo_set_string(head, "/");
295 } 293 }
296 294
297 /* List of namespaces. */ 295 /* List of namespaces. */
298 LIST_HEAD(tomoyo_namespace_list); 296 LIST_HEAD(tomoyo_namespace_list);
299 /* True if namespace other than tomoyo_kernel_namespace is defined. */ 297 /* True if namespace other than tomoyo_kernel_namespace is defined. */
300 static bool tomoyo_namespace_enabled; 298 static bool tomoyo_namespace_enabled;
301 299
302 /** 300 /**
303 * tomoyo_init_policy_namespace - Initialize namespace. 301 * tomoyo_init_policy_namespace - Initialize namespace.
304 * 302 *
305 * @ns: Pointer to "struct tomoyo_policy_namespace". 303 * @ns: Pointer to "struct tomoyo_policy_namespace".
306 * 304 *
307 * Returns nothing. 305 * Returns nothing.
308 */ 306 */
309 void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns) 307 void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
310 { 308 {
311 unsigned int idx; 309 unsigned int idx;
312 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++) 310 for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
313 INIT_LIST_HEAD(&ns->acl_group[idx]); 311 INIT_LIST_HEAD(&ns->acl_group[idx]);
314 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++) 312 for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
315 INIT_LIST_HEAD(&ns->group_list[idx]); 313 INIT_LIST_HEAD(&ns->group_list[idx]);
316 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++) 314 for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
317 INIT_LIST_HEAD(&ns->policy_list[idx]); 315 INIT_LIST_HEAD(&ns->policy_list[idx]);
318 ns->profile_version = 20100903; 316 ns->profile_version = 20100903;
319 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list); 317 tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
320 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list); 318 list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
321 } 319 }
322 320
323 /** 321 /**
324 * tomoyo_print_namespace - Print namespace header. 322 * tomoyo_print_namespace - Print namespace header.
325 * 323 *
326 * @head: Pointer to "struct tomoyo_io_buffer". 324 * @head: Pointer to "struct tomoyo_io_buffer".
327 * 325 *
328 * Returns nothing. 326 * Returns nothing.
329 */ 327 */
330 static void tomoyo_print_namespace(struct tomoyo_io_buffer *head) 328 static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
331 { 329 {
332 if (!tomoyo_namespace_enabled) 330 if (!tomoyo_namespace_enabled)
333 return; 331 return;
334 tomoyo_set_string(head, 332 tomoyo_set_string(head,
335 container_of(head->r.ns, 333 container_of(head->r.ns,
336 struct tomoyo_policy_namespace, 334 struct tomoyo_policy_namespace,
337 namespace_list)->name); 335 namespace_list)->name);
338 tomoyo_set_space(head); 336 tomoyo_set_space(head);
339 } 337 }
340 338
341 /** 339 /**
342 * tomoyo_print_name_union - Print a tomoyo_name_union. 340 * tomoyo_print_name_union - Print a tomoyo_name_union.
343 * 341 *
344 * @head: Pointer to "struct tomoyo_io_buffer". 342 * @head: Pointer to "struct tomoyo_io_buffer".
345 * @ptr: Pointer to "struct tomoyo_name_union". 343 * @ptr: Pointer to "struct tomoyo_name_union".
346 */ 344 */
347 static void tomoyo_print_name_union(struct tomoyo_io_buffer *head, 345 static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
348 const struct tomoyo_name_union *ptr) 346 const struct tomoyo_name_union *ptr)
349 { 347 {
350 tomoyo_set_space(head); 348 tomoyo_set_space(head);
351 if (ptr->group) { 349 if (ptr->group) {
352 tomoyo_set_string(head, "@"); 350 tomoyo_set_string(head, "@");
353 tomoyo_set_string(head, ptr->group->group_name->name); 351 tomoyo_set_string(head, ptr->group->group_name->name);
354 } else { 352 } else {
355 tomoyo_set_string(head, ptr->filename->name); 353 tomoyo_set_string(head, ptr->filename->name);
356 } 354 }
357 } 355 }
358 356
359 /** 357 /**
360 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote. 358 * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
361 * 359 *
362 * @head: Pointer to "struct tomoyo_io_buffer". 360 * @head: Pointer to "struct tomoyo_io_buffer".
363 * @ptr: Pointer to "struct tomoyo_name_union". 361 * @ptr: Pointer to "struct tomoyo_name_union".
364 * 362 *
365 * Returns nothing. 363 * Returns nothing.
366 */ 364 */
367 static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head, 365 static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
368 const struct tomoyo_name_union *ptr) 366 const struct tomoyo_name_union *ptr)
369 { 367 {
370 if (ptr->group) { 368 if (ptr->group) {
371 tomoyo_set_string(head, "@"); 369 tomoyo_set_string(head, "@");
372 tomoyo_set_string(head, ptr->group->group_name->name); 370 tomoyo_set_string(head, ptr->group->group_name->name);
373 } else { 371 } else {
374 tomoyo_set_string(head, "\""); 372 tomoyo_set_string(head, "\"");
375 tomoyo_set_string(head, ptr->filename->name); 373 tomoyo_set_string(head, ptr->filename->name);
376 tomoyo_set_string(head, "\""); 374 tomoyo_set_string(head, "\"");
377 } 375 }
378 } 376 }
379 377
380 /** 378 /**
381 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space. 379 * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
382 * 380 *
383 * @head: Pointer to "struct tomoyo_io_buffer". 381 * @head: Pointer to "struct tomoyo_io_buffer".
384 * @ptr: Pointer to "struct tomoyo_number_union". 382 * @ptr: Pointer to "struct tomoyo_number_union".
385 * 383 *
386 * Returns nothing. 384 * Returns nothing.
387 */ 385 */
388 static void tomoyo_print_number_union_nospace 386 static void tomoyo_print_number_union_nospace
389 (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr) 387 (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr)
390 { 388 {
391 if (ptr->group) { 389 if (ptr->group) {
392 tomoyo_set_string(head, "@"); 390 tomoyo_set_string(head, "@");
393 tomoyo_set_string(head, ptr->group->group_name->name); 391 tomoyo_set_string(head, ptr->group->group_name->name);
394 } else { 392 } else {
395 int i; 393 int i;
396 unsigned long min = ptr->values[0]; 394 unsigned long min = ptr->values[0];
397 const unsigned long max = ptr->values[1]; 395 const unsigned long max = ptr->values[1];
398 u8 min_type = ptr->value_type[0]; 396 u8 min_type = ptr->value_type[0];
399 const u8 max_type = ptr->value_type[1]; 397 const u8 max_type = ptr->value_type[1];
400 char buffer[128]; 398 char buffer[128];
401 buffer[0] = '\0'; 399 buffer[0] = '\0';
402 for (i = 0; i < 2; i++) { 400 for (i = 0; i < 2; i++) {
403 switch (min_type) { 401 switch (min_type) {
404 case TOMOYO_VALUE_TYPE_HEXADECIMAL: 402 case TOMOYO_VALUE_TYPE_HEXADECIMAL:
405 tomoyo_addprintf(buffer, sizeof(buffer), 403 tomoyo_addprintf(buffer, sizeof(buffer),
406 "0x%lX", min); 404 "0x%lX", min);
407 break; 405 break;
408 case TOMOYO_VALUE_TYPE_OCTAL: 406 case TOMOYO_VALUE_TYPE_OCTAL:
409 tomoyo_addprintf(buffer, sizeof(buffer), 407 tomoyo_addprintf(buffer, sizeof(buffer),
410 "0%lo", min); 408 "0%lo", min);
411 break; 409 break;
412 default: 410 default:
413 tomoyo_addprintf(buffer, sizeof(buffer), "%lu", 411 tomoyo_addprintf(buffer, sizeof(buffer), "%lu",
414 min); 412 min);
415 break; 413 break;
416 } 414 }
417 if (min == max && min_type == max_type) 415 if (min == max && min_type == max_type)
418 break; 416 break;
419 tomoyo_addprintf(buffer, sizeof(buffer), "-"); 417 tomoyo_addprintf(buffer, sizeof(buffer), "-");
420 min_type = max_type; 418 min_type = max_type;
421 min = max; 419 min = max;
422 } 420 }
423 tomoyo_io_printf(head, "%s", buffer); 421 tomoyo_io_printf(head, "%s", buffer);
424 } 422 }
425 } 423 }
426 424
427 /** 425 /**
428 * tomoyo_print_number_union - Print a tomoyo_number_union. 426 * tomoyo_print_number_union - Print a tomoyo_number_union.
429 * 427 *
430 * @head: Pointer to "struct tomoyo_io_buffer". 428 * @head: Pointer to "struct tomoyo_io_buffer".
431 * @ptr: Pointer to "struct tomoyo_number_union". 429 * @ptr: Pointer to "struct tomoyo_number_union".
432 * 430 *
433 * Returns nothing. 431 * Returns nothing.
434 */ 432 */
435 static void tomoyo_print_number_union(struct tomoyo_io_buffer *head, 433 static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
436 const struct tomoyo_number_union *ptr) 434 const struct tomoyo_number_union *ptr)
437 { 435 {
438 tomoyo_set_space(head); 436 tomoyo_set_space(head);
439 tomoyo_print_number_union_nospace(head, ptr); 437 tomoyo_print_number_union_nospace(head, ptr);
440 } 438 }
441 439
442 /** 440 /**
443 * tomoyo_assign_profile - Create a new profile. 441 * tomoyo_assign_profile - Create a new profile.
444 * 442 *
445 * @ns: Pointer to "struct tomoyo_policy_namespace". 443 * @ns: Pointer to "struct tomoyo_policy_namespace".
446 * @profile: Profile number to create. 444 * @profile: Profile number to create.
447 * 445 *
448 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise. 446 * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
449 */ 447 */
450 static struct tomoyo_profile *tomoyo_assign_profile 448 static struct tomoyo_profile *tomoyo_assign_profile
451 (struct tomoyo_policy_namespace *ns, const unsigned int profile) 449 (struct tomoyo_policy_namespace *ns, const unsigned int profile)
452 { 450 {
453 struct tomoyo_profile *ptr; 451 struct tomoyo_profile *ptr;
454 struct tomoyo_profile *entry; 452 struct tomoyo_profile *entry;
455 if (profile >= TOMOYO_MAX_PROFILES) 453 if (profile >= TOMOYO_MAX_PROFILES)
456 return NULL; 454 return NULL;
457 ptr = ns->profile_ptr[profile]; 455 ptr = ns->profile_ptr[profile];
458 if (ptr) 456 if (ptr)
459 return ptr; 457 return ptr;
460 entry = kzalloc(sizeof(*entry), GFP_NOFS); 458 entry = kzalloc(sizeof(*entry), GFP_NOFS);
461 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 459 if (mutex_lock_interruptible(&tomoyo_policy_lock))
462 goto out; 460 goto out;
463 ptr = ns->profile_ptr[profile]; 461 ptr = ns->profile_ptr[profile];
464 if (!ptr && tomoyo_memory_ok(entry)) { 462 if (!ptr && tomoyo_memory_ok(entry)) {
465 ptr = entry; 463 ptr = entry;
466 ptr->default_config = TOMOYO_CONFIG_DISABLED | 464 ptr->default_config = TOMOYO_CONFIG_DISABLED |
467 TOMOYO_CONFIG_WANT_GRANT_LOG | 465 TOMOYO_CONFIG_WANT_GRANT_LOG |
468 TOMOYO_CONFIG_WANT_REJECT_LOG; 466 TOMOYO_CONFIG_WANT_REJECT_LOG;
469 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT, 467 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
470 sizeof(ptr->config)); 468 sizeof(ptr->config));
471 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024; 469 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] = 1024;
472 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048; 470 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] = 2048;
473 mb(); /* Avoid out-of-order execution. */ 471 mb(); /* Avoid out-of-order execution. */
474 ns->profile_ptr[profile] = ptr; 472 ns->profile_ptr[profile] = ptr;
475 entry = NULL; 473 entry = NULL;
476 } 474 }
477 mutex_unlock(&tomoyo_policy_lock); 475 mutex_unlock(&tomoyo_policy_lock);
478 out: 476 out:
479 kfree(entry); 477 kfree(entry);
480 return ptr; 478 return ptr;
481 } 479 }
482 480
483 /** 481 /**
484 * tomoyo_profile - Find a profile. 482 * tomoyo_profile - Find a profile.
485 * 483 *
486 * @ns: Pointer to "struct tomoyo_policy_namespace". 484 * @ns: Pointer to "struct tomoyo_policy_namespace".
487 * @profile: Profile number to find. 485 * @profile: Profile number to find.
488 * 486 *
489 * Returns pointer to "struct tomoyo_profile". 487 * Returns pointer to "struct tomoyo_profile".
490 */ 488 */
491 struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns, 489 struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
492 const u8 profile) 490 const u8 profile)
493 { 491 {
494 static struct tomoyo_profile tomoyo_null_profile; 492 static struct tomoyo_profile tomoyo_null_profile;
495 struct tomoyo_profile *ptr = ns->profile_ptr[profile]; 493 struct tomoyo_profile *ptr = ns->profile_ptr[profile];
496 if (!ptr) 494 if (!ptr)
497 ptr = &tomoyo_null_profile; 495 ptr = &tomoyo_null_profile;
498 return ptr; 496 return ptr;
499 } 497 }
500 498
501 /** 499 /**
502 * tomoyo_find_yesno - Find values for specified keyword. 500 * tomoyo_find_yesno - Find values for specified keyword.
503 * 501 *
504 * @string: String to check. 502 * @string: String to check.
505 * @find: Name of keyword. 503 * @find: Name of keyword.
506 * 504 *
507 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise. 505 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
508 */ 506 */
509 static s8 tomoyo_find_yesno(const char *string, const char *find) 507 static s8 tomoyo_find_yesno(const char *string, const char *find)
510 { 508 {
511 const char *cp = strstr(string, find); 509 const char *cp = strstr(string, find);
512 if (cp) { 510 if (cp) {
513 cp += strlen(find); 511 cp += strlen(find);
514 if (!strncmp(cp, "=yes", 4)) 512 if (!strncmp(cp, "=yes", 4))
515 return 1; 513 return 1;
516 else if (!strncmp(cp, "=no", 3)) 514 else if (!strncmp(cp, "=no", 3))
517 return 0; 515 return 0;
518 } 516 }
519 return -1; 517 return -1;
520 } 518 }
521 519
522 /** 520 /**
523 * tomoyo_set_uint - Set value for specified preference. 521 * tomoyo_set_uint - Set value for specified preference.
524 * 522 *
525 * @i: Pointer to "unsigned int". 523 * @i: Pointer to "unsigned int".
526 * @string: String to check. 524 * @string: String to check.
527 * @find: Name of keyword. 525 * @find: Name of keyword.
528 * 526 *
529 * Returns nothing. 527 * Returns nothing.
530 */ 528 */
531 static void tomoyo_set_uint(unsigned int *i, const char *string, 529 static void tomoyo_set_uint(unsigned int *i, const char *string,
532 const char *find) 530 const char *find)
533 { 531 {
534 const char *cp = strstr(string, find); 532 const char *cp = strstr(string, find);
535 if (cp) 533 if (cp)
536 sscanf(cp + strlen(find), "=%u", i); 534 sscanf(cp + strlen(find), "=%u", i);
537 } 535 }
538 536
539 /** 537 /**
540 * tomoyo_set_mode - Set mode for specified profile. 538 * tomoyo_set_mode - Set mode for specified profile.
541 * 539 *
542 * @name: Name of functionality. 540 * @name: Name of functionality.
543 * @value: Mode for @name. 541 * @value: Mode for @name.
544 * @profile: Pointer to "struct tomoyo_profile". 542 * @profile: Pointer to "struct tomoyo_profile".
545 * 543 *
546 * Returns 0 on success, negative value otherwise. 544 * Returns 0 on success, negative value otherwise.
547 */ 545 */
548 static int tomoyo_set_mode(char *name, const char *value, 546 static int tomoyo_set_mode(char *name, const char *value,
549 struct tomoyo_profile *profile) 547 struct tomoyo_profile *profile)
550 { 548 {
551 u8 i; 549 u8 i;
552 u8 config; 550 u8 config;
553 if (!strcmp(name, "CONFIG")) { 551 if (!strcmp(name, "CONFIG")) {
554 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX; 552 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
555 config = profile->default_config; 553 config = profile->default_config;
556 } else if (tomoyo_str_starts(&name, "CONFIG::")) { 554 } else if (tomoyo_str_starts(&name, "CONFIG::")) {
557 config = 0; 555 config = 0;
558 for (i = 0; i < TOMOYO_MAX_MAC_INDEX 556 for (i = 0; i < TOMOYO_MAX_MAC_INDEX
559 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) { 557 + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
560 int len = 0; 558 int len = 0;
561 if (i < TOMOYO_MAX_MAC_INDEX) { 559 if (i < TOMOYO_MAX_MAC_INDEX) {
562 const u8 c = tomoyo_index2category[i]; 560 const u8 c = tomoyo_index2category[i];
563 const char *category = 561 const char *category =
564 tomoyo_category_keywords[c]; 562 tomoyo_category_keywords[c];
565 len = strlen(category); 563 len = strlen(category);
566 if (strncmp(name, category, len) || 564 if (strncmp(name, category, len) ||
567 name[len++] != ':' || name[len++] != ':') 565 name[len++] != ':' || name[len++] != ':')
568 continue; 566 continue;
569 } 567 }
570 if (strcmp(name + len, tomoyo_mac_keywords[i])) 568 if (strcmp(name + len, tomoyo_mac_keywords[i]))
571 continue; 569 continue;
572 config = profile->config[i]; 570 config = profile->config[i];
573 break; 571 break;
574 } 572 }
575 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 573 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
576 return -EINVAL; 574 return -EINVAL;
577 } else { 575 } else {
578 return -EINVAL; 576 return -EINVAL;
579 } 577 }
580 if (strstr(value, "use_default")) { 578 if (strstr(value, "use_default")) {
581 config = TOMOYO_CONFIG_USE_DEFAULT; 579 config = TOMOYO_CONFIG_USE_DEFAULT;
582 } else { 580 } else {
583 u8 mode; 581 u8 mode;
584 for (mode = 0; mode < 4; mode++) 582 for (mode = 0; mode < 4; mode++)
585 if (strstr(value, tomoyo_mode[mode])) 583 if (strstr(value, tomoyo_mode[mode]))
586 /* 584 /*
587 * Update lower 3 bits in order to distinguish 585 * Update lower 3 bits in order to distinguish
588 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'. 586 * 'config' from 'TOMOYO_CONFIG_USE_DEAFULT'.
589 */ 587 */
590 config = (config & ~7) | mode; 588 config = (config & ~7) | mode;
591 if (config != TOMOYO_CONFIG_USE_DEFAULT) { 589 if (config != TOMOYO_CONFIG_USE_DEFAULT) {
592 switch (tomoyo_find_yesno(value, "grant_log")) { 590 switch (tomoyo_find_yesno(value, "grant_log")) {
593 case 1: 591 case 1:
594 config |= TOMOYO_CONFIG_WANT_GRANT_LOG; 592 config |= TOMOYO_CONFIG_WANT_GRANT_LOG;
595 break; 593 break;
596 case 0: 594 case 0:
597 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG; 595 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG;
598 break; 596 break;
599 } 597 }
600 switch (tomoyo_find_yesno(value, "reject_log")) { 598 switch (tomoyo_find_yesno(value, "reject_log")) {
601 case 1: 599 case 1:
602 config |= TOMOYO_CONFIG_WANT_REJECT_LOG; 600 config |= TOMOYO_CONFIG_WANT_REJECT_LOG;
603 break; 601 break;
604 case 0: 602 case 0:
605 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG; 603 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG;
606 break; 604 break;
607 } 605 }
608 } 606 }
609 } 607 }
610 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX) 608 if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
611 profile->config[i] = config; 609 profile->config[i] = config;
612 else if (config != TOMOYO_CONFIG_USE_DEFAULT) 610 else if (config != TOMOYO_CONFIG_USE_DEFAULT)
613 profile->default_config = config; 611 profile->default_config = config;
614 return 0; 612 return 0;
615 } 613 }
616 614
617 /** 615 /**
618 * tomoyo_write_profile - Write profile table. 616 * tomoyo_write_profile - Write profile table.
619 * 617 *
620 * @head: Pointer to "struct tomoyo_io_buffer". 618 * @head: Pointer to "struct tomoyo_io_buffer".
621 * 619 *
622 * Returns 0 on success, negative value otherwise. 620 * Returns 0 on success, negative value otherwise.
623 */ 621 */
624 static int tomoyo_write_profile(struct tomoyo_io_buffer *head) 622 static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
625 { 623 {
626 char *data = head->write_buf; 624 char *data = head->write_buf;
627 unsigned int i; 625 unsigned int i;
628 char *cp; 626 char *cp;
629 struct tomoyo_profile *profile; 627 struct tomoyo_profile *profile;
630 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) 628 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
631 == 1) 629 == 1)
632 return 0; 630 return 0;
633 i = simple_strtoul(data, &cp, 10); 631 i = simple_strtoul(data, &cp, 10);
634 if (*cp != '-') 632 if (*cp != '-')
635 return -EINVAL; 633 return -EINVAL;
636 data = cp + 1; 634 data = cp + 1;
637 profile = tomoyo_assign_profile(head->w.ns, i); 635 profile = tomoyo_assign_profile(head->w.ns, i);
638 if (!profile) 636 if (!profile)
639 return -EINVAL; 637 return -EINVAL;
640 cp = strchr(data, '='); 638 cp = strchr(data, '=');
641 if (!cp) 639 if (!cp)
642 return -EINVAL; 640 return -EINVAL;
643 *cp++ = '\0'; 641 *cp++ = '\0';
644 if (!strcmp(data, "COMMENT")) { 642 if (!strcmp(data, "COMMENT")) {
645 static DEFINE_SPINLOCK(lock); 643 static DEFINE_SPINLOCK(lock);
646 const struct tomoyo_path_info *new_comment 644 const struct tomoyo_path_info *new_comment
647 = tomoyo_get_name(cp); 645 = tomoyo_get_name(cp);
648 const struct tomoyo_path_info *old_comment; 646 const struct tomoyo_path_info *old_comment;
649 if (!new_comment) 647 if (!new_comment)
650 return -ENOMEM; 648 return -ENOMEM;
651 spin_lock(&lock); 649 spin_lock(&lock);
652 old_comment = profile->comment; 650 old_comment = profile->comment;
653 profile->comment = new_comment; 651 profile->comment = new_comment;
654 spin_unlock(&lock); 652 spin_unlock(&lock);
655 tomoyo_put_name(old_comment); 653 tomoyo_put_name(old_comment);
656 return 0; 654 return 0;
657 } 655 }
658 if (!strcmp(data, "PREFERENCE")) { 656 if (!strcmp(data, "PREFERENCE")) {
659 for (i = 0; i < TOMOYO_MAX_PREF; i++) 657 for (i = 0; i < TOMOYO_MAX_PREF; i++)
660 tomoyo_set_uint(&profile->pref[i], cp, 658 tomoyo_set_uint(&profile->pref[i], cp,
661 tomoyo_pref_keywords[i]); 659 tomoyo_pref_keywords[i]);
662 return 0; 660 return 0;
663 } 661 }
664 return tomoyo_set_mode(data, cp, profile); 662 return tomoyo_set_mode(data, cp, profile);
665 } 663 }
666 664
667 /** 665 /**
668 * tomoyo_print_config - Print mode for specified functionality. 666 * tomoyo_print_config - Print mode for specified functionality.
669 * 667 *
670 * @head: Pointer to "struct tomoyo_io_buffer". 668 * @head: Pointer to "struct tomoyo_io_buffer".
671 * @config: Mode for that functionality. 669 * @config: Mode for that functionality.
672 * 670 *
673 * Returns nothing. 671 * Returns nothing.
674 * 672 *
675 * Caller prints functionality's name. 673 * Caller prints functionality's name.
676 */ 674 */
677 static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config) 675 static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
678 { 676 {
679 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n", 677 tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
680 tomoyo_mode[config & 3], 678 tomoyo_mode[config & 3],
681 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_GRANT_LOG), 679 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_GRANT_LOG),
682 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_REJECT_LOG)); 680 tomoyo_yesno(config & TOMOYO_CONFIG_WANT_REJECT_LOG));
683 } 681 }
684 682
685 /** 683 /**
686 * tomoyo_read_profile - Read profile table. 684 * tomoyo_read_profile - Read profile table.
687 * 685 *
688 * @head: Pointer to "struct tomoyo_io_buffer". 686 * @head: Pointer to "struct tomoyo_io_buffer".
689 * 687 *
690 * Returns nothing. 688 * Returns nothing.
691 */ 689 */
692 static void tomoyo_read_profile(struct tomoyo_io_buffer *head) 690 static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
693 { 691 {
694 u8 index; 692 u8 index;
695 struct tomoyo_policy_namespace *ns = 693 struct tomoyo_policy_namespace *ns =
696 container_of(head->r.ns, typeof(*ns), namespace_list); 694 container_of(head->r.ns, typeof(*ns), namespace_list);
697 const struct tomoyo_profile *profile; 695 const struct tomoyo_profile *profile;
698 if (head->r.eof) 696 if (head->r.eof)
699 return; 697 return;
700 next: 698 next:
701 index = head->r.index; 699 index = head->r.index;
702 profile = ns->profile_ptr[index]; 700 profile = ns->profile_ptr[index];
703 switch (head->r.step) { 701 switch (head->r.step) {
704 case 0: 702 case 0:
705 tomoyo_print_namespace(head); 703 tomoyo_print_namespace(head);
706 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n", 704 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
707 ns->profile_version); 705 ns->profile_version);
708 head->r.step++; 706 head->r.step++;
709 break; 707 break;
710 case 1: 708 case 1:
711 for ( ; head->r.index < TOMOYO_MAX_PROFILES; 709 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
712 head->r.index++) 710 head->r.index++)
713 if (ns->profile_ptr[head->r.index]) 711 if (ns->profile_ptr[head->r.index])
714 break; 712 break;
715 if (head->r.index == TOMOYO_MAX_PROFILES) 713 if (head->r.index == TOMOYO_MAX_PROFILES)
716 return; 714 return;
717 head->r.step++; 715 head->r.step++;
718 break; 716 break;
719 case 2: 717 case 2:
720 { 718 {
721 u8 i; 719 u8 i;
722 const struct tomoyo_path_info *comment = 720 const struct tomoyo_path_info *comment =
723 profile->comment; 721 profile->comment;
724 tomoyo_print_namespace(head); 722 tomoyo_print_namespace(head);
725 tomoyo_io_printf(head, "%u-COMMENT=", index); 723 tomoyo_io_printf(head, "%u-COMMENT=", index);
726 tomoyo_set_string(head, comment ? comment->name : ""); 724 tomoyo_set_string(head, comment ? comment->name : "");
727 tomoyo_set_lf(head); 725 tomoyo_set_lf(head);
728 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index); 726 tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
729 for (i = 0; i < TOMOYO_MAX_PREF; i++) 727 for (i = 0; i < TOMOYO_MAX_PREF; i++)
730 tomoyo_io_printf(head, "%s=%u ", 728 tomoyo_io_printf(head, "%s=%u ",
731 tomoyo_pref_keywords[i], 729 tomoyo_pref_keywords[i],
732 profile->pref[i]); 730 profile->pref[i]);
733 tomoyo_set_string(head, "}\n"); 731 tomoyo_set_string(head, "}\n");
734 head->r.step++; 732 head->r.step++;
735 } 733 }
736 break; 734 break;
737 case 3: 735 case 3:
738 { 736 {
739 tomoyo_print_namespace(head); 737 tomoyo_print_namespace(head);
740 tomoyo_io_printf(head, "%u-%s", index, "CONFIG"); 738 tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
741 tomoyo_print_config(head, profile->default_config); 739 tomoyo_print_config(head, profile->default_config);
742 head->r.bit = 0; 740 head->r.bit = 0;
743 head->r.step++; 741 head->r.step++;
744 } 742 }
745 break; 743 break;
746 case 4: 744 case 4:
747 for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX 745 for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX
748 + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { 746 + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
749 const u8 i = head->r.bit; 747 const u8 i = head->r.bit;
750 const u8 config = profile->config[i]; 748 const u8 config = profile->config[i];
751 if (config == TOMOYO_CONFIG_USE_DEFAULT) 749 if (config == TOMOYO_CONFIG_USE_DEFAULT)
752 continue; 750 continue;
753 tomoyo_print_namespace(head); 751 tomoyo_print_namespace(head);
754 if (i < TOMOYO_MAX_MAC_INDEX) 752 if (i < TOMOYO_MAX_MAC_INDEX)
755 tomoyo_io_printf(head, "%u-CONFIG::%s::%s", 753 tomoyo_io_printf(head, "%u-CONFIG::%s::%s",
756 index, 754 index,
757 tomoyo_category_keywords 755 tomoyo_category_keywords
758 [tomoyo_index2category[i]], 756 [tomoyo_index2category[i]],
759 tomoyo_mac_keywords[i]); 757 tomoyo_mac_keywords[i]);
760 else 758 else
761 tomoyo_io_printf(head, "%u-CONFIG::%s", index, 759 tomoyo_io_printf(head, "%u-CONFIG::%s", index,
762 tomoyo_mac_keywords[i]); 760 tomoyo_mac_keywords[i]);
763 tomoyo_print_config(head, config); 761 tomoyo_print_config(head, config);
764 head->r.bit++; 762 head->r.bit++;
765 break; 763 break;
766 } 764 }
767 if (head->r.bit == TOMOYO_MAX_MAC_INDEX 765 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
768 + TOMOYO_MAX_MAC_CATEGORY_INDEX) { 766 + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
769 head->r.index++; 767 head->r.index++;
770 head->r.step = 1; 768 head->r.step = 1;
771 } 769 }
772 break; 770 break;
773 } 771 }
774 if (tomoyo_flush(head)) 772 if (tomoyo_flush(head))
775 goto next; 773 goto next;
776 } 774 }
777 775
776 /**
777 * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry.
778 *
779 * @a: Pointer to "struct tomoyo_acl_head".
780 * @b: Pointer to "struct tomoyo_acl_head".
781 *
782 * Returns true if @a == @b, false otherwise.
783 */
778 static bool tomoyo_same_manager(const struct tomoyo_acl_head *a, 784 static bool tomoyo_same_manager(const struct tomoyo_acl_head *a,
779 const struct tomoyo_acl_head *b) 785 const struct tomoyo_acl_head *b)
780 { 786 {
781 return container_of(a, struct tomoyo_manager, head)->manager == 787 return container_of(a, struct tomoyo_manager, head)->manager ==
782 container_of(b, struct tomoyo_manager, head)->manager; 788 container_of(b, struct tomoyo_manager, head)->manager;
783 } 789 }
784 790
785 /** 791 /**
786 * tomoyo_update_manager_entry - Add a manager entry. 792 * tomoyo_update_manager_entry - Add a manager entry.
787 * 793 *
788 * @manager: The path to manager or the domainnamme. 794 * @manager: The path to manager or the domainnamme.
789 * @is_delete: True if it is a delete request. 795 * @is_delete: True if it is a delete request.
790 * 796 *
791 * Returns 0 on success, negative value otherwise. 797 * Returns 0 on success, negative value otherwise.
792 * 798 *
793 * Caller holds tomoyo_read_lock(). 799 * Caller holds tomoyo_read_lock().
794 */ 800 */
795 static int tomoyo_update_manager_entry(const char *manager, 801 static int tomoyo_update_manager_entry(const char *manager,
796 const bool is_delete) 802 const bool is_delete)
797 { 803 {
798 struct tomoyo_manager e = { }; 804 struct tomoyo_manager e = { };
799 struct tomoyo_acl_param param = { 805 struct tomoyo_acl_param param = {
800 /* .ns = &tomoyo_kernel_namespace, */ 806 /* .ns = &tomoyo_kernel_namespace, */
801 .is_delete = is_delete, 807 .is_delete = is_delete,
802 .list = &tomoyo_kernel_namespace. 808 .list = &tomoyo_kernel_namespace.
803 policy_list[TOMOYO_ID_MANAGER], 809 policy_list[TOMOYO_ID_MANAGER],
804 }; 810 };
805 int error = is_delete ? -ENOENT : -ENOMEM; 811 int error = is_delete ? -ENOENT : -ENOMEM;
806 if (tomoyo_domain_def(manager)) { 812 if (tomoyo_domain_def(manager)) {
807 if (!tomoyo_correct_domain(manager)) 813 if (!tomoyo_correct_domain(manager))
808 return -EINVAL; 814 return -EINVAL;
809 e.is_domain = true; 815 e.is_domain = true;
810 } else { 816 } else {
811 if (!tomoyo_correct_path(manager)) 817 if (!tomoyo_correct_path(manager))
812 return -EINVAL; 818 return -EINVAL;
813 } 819 }
814 e.manager = tomoyo_get_name(manager); 820 e.manager = tomoyo_get_name(manager);
815 if (e.manager) { 821 if (e.manager) {
816 error = tomoyo_update_policy(&e.head, sizeof(e), &param, 822 error = tomoyo_update_policy(&e.head, sizeof(e), &param,
817 tomoyo_same_manager); 823 tomoyo_same_manager);
818 tomoyo_put_name(e.manager); 824 tomoyo_put_name(e.manager);
819 } 825 }
820 return error; 826 return error;
821 } 827 }
822 828
823 /** 829 /**
824 * tomoyo_write_manager - Write manager policy. 830 * tomoyo_write_manager - Write manager policy.
825 * 831 *
826 * @head: Pointer to "struct tomoyo_io_buffer". 832 * @head: Pointer to "struct tomoyo_io_buffer".
827 * 833 *
828 * Returns 0 on success, negative value otherwise. 834 * Returns 0 on success, negative value otherwise.
829 * 835 *
830 * Caller holds tomoyo_read_lock(). 836 * Caller holds tomoyo_read_lock().
831 */ 837 */
832 static int tomoyo_write_manager(struct tomoyo_io_buffer *head) 838 static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
833 { 839 {
834 char *data = head->write_buf; 840 char *data = head->write_buf;
835 841
836 if (!strcmp(data, "manage_by_non_root")) { 842 if (!strcmp(data, "manage_by_non_root")) {
837 tomoyo_manage_by_non_root = !head->w.is_delete; 843 tomoyo_manage_by_non_root = !head->w.is_delete;
838 return 0; 844 return 0;
839 } 845 }
840 return tomoyo_update_manager_entry(data, head->w.is_delete); 846 return tomoyo_update_manager_entry(data, head->w.is_delete);
841 } 847 }
842 848
843 /** 849 /**
844 * tomoyo_read_manager - Read manager policy. 850 * tomoyo_read_manager - Read manager policy.
845 * 851 *
846 * @head: Pointer to "struct tomoyo_io_buffer". 852 * @head: Pointer to "struct tomoyo_io_buffer".
847 * 853 *
848 * Caller holds tomoyo_read_lock(). 854 * Caller holds tomoyo_read_lock().
849 */ 855 */
850 static void tomoyo_read_manager(struct tomoyo_io_buffer *head) 856 static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
851 { 857 {
852 if (head->r.eof) 858 if (head->r.eof)
853 return; 859 return;
854 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace. 860 list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.
855 policy_list[TOMOYO_ID_MANAGER]) { 861 policy_list[TOMOYO_ID_MANAGER]) {
856 struct tomoyo_manager *ptr = 862 struct tomoyo_manager *ptr =
857 list_entry(head->r.acl, typeof(*ptr), head.list); 863 list_entry(head->r.acl, typeof(*ptr), head.list);
858 if (ptr->head.is_deleted) 864 if (ptr->head.is_deleted)
859 continue; 865 continue;
860 if (!tomoyo_flush(head)) 866 if (!tomoyo_flush(head))
861 return; 867 return;
862 tomoyo_set_string(head, ptr->manager->name); 868 tomoyo_set_string(head, ptr->manager->name);
863 tomoyo_set_lf(head); 869 tomoyo_set_lf(head);
864 } 870 }
865 head->r.eof = true; 871 head->r.eof = true;
866 } 872 }
867 873
868 /** 874 /**
869 * tomoyo_manager - Check whether the current process is a policy manager. 875 * tomoyo_manager - Check whether the current process is a policy manager.
870 * 876 *
871 * Returns true if the current process is permitted to modify policy 877 * Returns true if the current process is permitted to modify policy
872 * via /sys/kernel/security/tomoyo/ interface. 878 * via /sys/kernel/security/tomoyo/ interface.
873 * 879 *
874 * Caller holds tomoyo_read_lock(). 880 * Caller holds tomoyo_read_lock().
875 */ 881 */
876 static bool tomoyo_manager(void) 882 static bool tomoyo_manager(void)
877 { 883 {
878 struct tomoyo_manager *ptr; 884 struct tomoyo_manager *ptr;
879 const char *exe; 885 const char *exe;
880 const struct task_struct *task = current; 886 const struct task_struct *task = current;
881 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname; 887 const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
882 bool found = false; 888 bool found = false;
883 889
884 if (!tomoyo_policy_loaded) 890 if (!tomoyo_policy_loaded)
885 return true; 891 return true;
886 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 892 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
887 return false; 893 return false;
888 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. 894 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
889 policy_list[TOMOYO_ID_MANAGER], head.list) { 895 policy_list[TOMOYO_ID_MANAGER], head.list) {
890 if (!ptr->head.is_deleted && ptr->is_domain 896 if (!ptr->head.is_deleted && ptr->is_domain
891 && !tomoyo_pathcmp(domainname, ptr->manager)) { 897 && !tomoyo_pathcmp(domainname, ptr->manager)) {
892 found = true; 898 found = true;
893 break; 899 break;
894 } 900 }
895 } 901 }
896 if (found) 902 if (found)
897 return true; 903 return true;
898 exe = tomoyo_get_exe(); 904 exe = tomoyo_get_exe();
899 if (!exe) 905 if (!exe)
900 return false; 906 return false;
901 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace. 907 list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.
902 policy_list[TOMOYO_ID_MANAGER], head.list) { 908 policy_list[TOMOYO_ID_MANAGER], head.list) {
903 if (!ptr->head.is_deleted && !ptr->is_domain 909 if (!ptr->head.is_deleted && !ptr->is_domain
904 && !strcmp(exe, ptr->manager->name)) { 910 && !strcmp(exe, ptr->manager->name)) {
905 found = true; 911 found = true;
906 break; 912 break;
907 } 913 }
908 } 914 }
909 if (!found) { /* Reduce error messages. */ 915 if (!found) { /* Reduce error messages. */
910 static pid_t last_pid; 916 static pid_t last_pid;
911 const pid_t pid = current->pid; 917 const pid_t pid = current->pid;
912 if (last_pid != pid) { 918 if (last_pid != pid) {
913 printk(KERN_WARNING "%s ( %s ) is not permitted to " 919 printk(KERN_WARNING "%s ( %s ) is not permitted to "
914 "update policies.\n", domainname->name, exe); 920 "update policies.\n", domainname->name, exe);
915 last_pid = pid; 921 last_pid = pid;
916 } 922 }
917 } 923 }
918 kfree(exe); 924 kfree(exe);
919 return found; 925 return found;
920 } 926 }
921 927
922 /** 928 /**
923 * tomoyo_select_domain - Parse select command. 929 * tomoyo_select_domain - Parse select command.
924 * 930 *
925 * @head: Pointer to "struct tomoyo_io_buffer". 931 * @head: Pointer to "struct tomoyo_io_buffer".
926 * @data: String to parse. 932 * @data: String to parse.
927 * 933 *
928 * Returns true on success, false otherwise. 934 * Returns true on success, false otherwise.
929 * 935 *
930 * Caller holds tomoyo_read_lock(). 936 * Caller holds tomoyo_read_lock().
931 */ 937 */
932 static bool tomoyo_select_domain(struct tomoyo_io_buffer *head, 938 static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
933 const char *data) 939 const char *data)
934 { 940 {
935 unsigned int pid; 941 unsigned int pid;
936 struct tomoyo_domain_info *domain = NULL; 942 struct tomoyo_domain_info *domain = NULL;
937 bool global_pid = false; 943 bool global_pid = false;
938 if (strncmp(data, "select ", 7)) 944 if (strncmp(data, "select ", 7))
939 return false; 945 return false;
940 data += 7; 946 data += 7;
941 if (sscanf(data, "pid=%u", &pid) == 1 || 947 if (sscanf(data, "pid=%u", &pid) == 1 ||
942 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 948 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
943 struct task_struct *p; 949 struct task_struct *p;
944 rcu_read_lock(); 950 rcu_read_lock();
945 read_lock(&tasklist_lock); 951 read_lock(&tasklist_lock);
946 if (global_pid) 952 if (global_pid)
947 p = find_task_by_pid_ns(pid, &init_pid_ns); 953 p = find_task_by_pid_ns(pid, &init_pid_ns);
948 else 954 else
949 p = find_task_by_vpid(pid); 955 p = find_task_by_vpid(pid);
950 if (p) 956 if (p)
951 domain = tomoyo_real_domain(p); 957 domain = tomoyo_real_domain(p);
952 read_unlock(&tasklist_lock); 958 read_unlock(&tasklist_lock);
953 rcu_read_unlock(); 959 rcu_read_unlock();
954 } else if (!strncmp(data, "domain=", 7)) { 960 } else if (!strncmp(data, "domain=", 7)) {
955 if (tomoyo_domain_def(data + 7)) 961 if (tomoyo_domain_def(data + 7))
956 domain = tomoyo_find_domain(data + 7); 962 domain = tomoyo_find_domain(data + 7);
957 } else 963 } else
958 return false; 964 return false;
959 head->w.domain = domain; 965 head->w.domain = domain;
960 /* Accessing read_buf is safe because head->io_sem is held. */ 966 /* Accessing read_buf is safe because head->io_sem is held. */
961 if (!head->read_buf) 967 if (!head->read_buf)
962 return true; /* Do nothing if open(O_WRONLY). */ 968 return true; /* Do nothing if open(O_WRONLY). */
963 memset(&head->r, 0, sizeof(head->r)); 969 memset(&head->r, 0, sizeof(head->r));
964 head->r.print_this_domain_only = true; 970 head->r.print_this_domain_only = true;
965 if (domain) 971 if (domain)
966 head->r.domain = &domain->list; 972 head->r.domain = &domain->list;
967 else 973 else
968 head->r.eof = 1; 974 head->r.eof = 1;
969 tomoyo_io_printf(head, "# select %s\n", data); 975 tomoyo_io_printf(head, "# select %s\n", data);
970 if (domain && domain->is_deleted) 976 if (domain && domain->is_deleted)
971 tomoyo_io_printf(head, "# This is a deleted domain.\n"); 977 tomoyo_io_printf(head, "# This is a deleted domain.\n");
972 return true; 978 return true;
973 } 979 }
974 980
975 /** 981 /**
976 * tomoyo_delete_domain - Delete a domain. 982 * tomoyo_delete_domain - Delete a domain.
977 * 983 *
978 * @domainname: The name of domain. 984 * @domainname: The name of domain.
979 * 985 *
980 * Returns 0. 986 * Returns 0.
981 * 987 *
982 * Caller holds tomoyo_read_lock(). 988 * Caller holds tomoyo_read_lock().
983 */ 989 */
984 static int tomoyo_delete_domain(char *domainname) 990 static int tomoyo_delete_domain(char *domainname)
985 { 991 {
986 struct tomoyo_domain_info *domain; 992 struct tomoyo_domain_info *domain;
987 struct tomoyo_path_info name; 993 struct tomoyo_path_info name;
988 994
989 name.name = domainname; 995 name.name = domainname;
990 tomoyo_fill_path_info(&name); 996 tomoyo_fill_path_info(&name);
991 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 997 if (mutex_lock_interruptible(&tomoyo_policy_lock))
992 return 0; 998 return 0;
993 /* Is there an active domain? */ 999 /* Is there an active domain? */
994 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1000 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
995 /* Never delete tomoyo_kernel_domain */ 1001 /* Never delete tomoyo_kernel_domain */
996 if (domain == &tomoyo_kernel_domain) 1002 if (domain == &tomoyo_kernel_domain)
997 continue; 1003 continue;
998 if (domain->is_deleted || 1004 if (domain->is_deleted ||
999 tomoyo_pathcmp(domain->domainname, &name)) 1005 tomoyo_pathcmp(domain->domainname, &name))
1000 continue; 1006 continue;
1001 domain->is_deleted = true; 1007 domain->is_deleted = true;
1002 break; 1008 break;
1003 } 1009 }
1004 mutex_unlock(&tomoyo_policy_lock); 1010 mutex_unlock(&tomoyo_policy_lock);
1005 return 0; 1011 return 0;
1006 } 1012 }
1007 1013
1008 /** 1014 /**
1009 * tomoyo_write_domain2 - Write domain policy. 1015 * tomoyo_write_domain2 - Write domain policy.
1010 * 1016 *
1011 * @ns: Pointer to "struct tomoyo_policy_namespace". 1017 * @ns: Pointer to "struct tomoyo_policy_namespace".
1012 * @list: Pointer to "struct list_head". 1018 * @list: Pointer to "struct list_head".
1013 * @data: Policy to be interpreted. 1019 * @data: Policy to be interpreted.
1014 * @is_delete: True if it is a delete request. 1020 * @is_delete: True if it is a delete request.
1015 * 1021 *
1016 * Returns 0 on success, negative value otherwise. 1022 * Returns 0 on success, negative value otherwise.
1017 * 1023 *
1018 * Caller holds tomoyo_read_lock(). 1024 * Caller holds tomoyo_read_lock().
1019 */ 1025 */
1020 static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns, 1026 static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
1021 struct list_head *list, char *data, 1027 struct list_head *list, char *data,
1022 const bool is_delete) 1028 const bool is_delete)
1023 { 1029 {
1024 struct tomoyo_acl_param param = { 1030 struct tomoyo_acl_param param = {
1025 .ns = ns, 1031 .ns = ns,
1026 .list = list, 1032 .list = list,
1027 .data = data, 1033 .data = data,
1028 .is_delete = is_delete, 1034 .is_delete = is_delete,
1029 }; 1035 };
1030 static const struct { 1036 static const struct {
1031 const char *keyword; 1037 const char *keyword;
1032 int (*write) (struct tomoyo_acl_param *); 1038 int (*write) (struct tomoyo_acl_param *);
1033 } tomoyo_callback[1] = { 1039 } tomoyo_callback[1] = {
1034 { "file ", tomoyo_write_file }, 1040 { "file ", tomoyo_write_file },
1035 }; 1041 };
1036 u8 i; 1042 u8 i;
1037 for (i = 0; i < 1; i++) { 1043 for (i = 0; i < 1; i++) {
1038 if (!tomoyo_str_starts(&param.data, 1044 if (!tomoyo_str_starts(&param.data,
1039 tomoyo_callback[i].keyword)) 1045 tomoyo_callback[i].keyword))
1040 continue; 1046 continue;
1041 return tomoyo_callback[i].write(&param); 1047 return tomoyo_callback[i].write(&param);
1042 } 1048 }
1043 return -EINVAL; 1049 return -EINVAL;
1044 } 1050 }
1045 1051
1046 /* String table for domain flags. */ 1052 /* String table for domain flags. */
1047 const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = { 1053 const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = {
1048 [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n", 1054 [TOMOYO_DIF_QUOTA_WARNED] = "quota_exceeded\n",
1049 [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n", 1055 [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n",
1050 }; 1056 };
1051 1057
1052 /** 1058 /**
1053 * tomoyo_write_domain - Write domain policy. 1059 * tomoyo_write_domain - Write domain policy.
1054 * 1060 *
1055 * @head: Pointer to "struct tomoyo_io_buffer". 1061 * @head: Pointer to "struct tomoyo_io_buffer".
1056 * 1062 *
1057 * Returns 0 on success, negative value otherwise. 1063 * Returns 0 on success, negative value otherwise.
1058 * 1064 *
1059 * Caller holds tomoyo_read_lock(). 1065 * Caller holds tomoyo_read_lock().
1060 */ 1066 */
1061 static int tomoyo_write_domain(struct tomoyo_io_buffer *head) 1067 static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
1062 { 1068 {
1063 char *data = head->write_buf; 1069 char *data = head->write_buf;
1064 struct tomoyo_policy_namespace *ns; 1070 struct tomoyo_policy_namespace *ns;
1065 struct tomoyo_domain_info *domain = head->w.domain; 1071 struct tomoyo_domain_info *domain = head->w.domain;
1066 const bool is_delete = head->w.is_delete; 1072 const bool is_delete = head->w.is_delete;
1067 bool is_select = !is_delete && tomoyo_str_starts(&data, "select "); 1073 bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
1068 unsigned int profile; 1074 unsigned int profile;
1069 if (*data == '<') { 1075 if (*data == '<') {
1070 domain = NULL; 1076 domain = NULL;
1071 if (is_delete) 1077 if (is_delete)
1072 tomoyo_delete_domain(data); 1078 tomoyo_delete_domain(data);
1073 else if (is_select) 1079 else if (is_select)
1074 domain = tomoyo_find_domain(data); 1080 domain = tomoyo_find_domain(data);
1075 else 1081 else
1076 domain = tomoyo_assign_domain(data, false); 1082 domain = tomoyo_assign_domain(data, false);
1077 head->w.domain = domain; 1083 head->w.domain = domain;
1078 return 0; 1084 return 0;
1079 } 1085 }
1080 if (!domain) 1086 if (!domain)
1081 return -EINVAL; 1087 return -EINVAL;
1082 ns = domain->ns; 1088 ns = domain->ns;
1083 if (sscanf(data, "use_profile %u", &profile) == 1 1089 if (sscanf(data, "use_profile %u", &profile) == 1
1084 && profile < TOMOYO_MAX_PROFILES) { 1090 && profile < TOMOYO_MAX_PROFILES) {
1085 if (!tomoyo_policy_loaded || ns->profile_ptr[profile]) 1091 if (!tomoyo_policy_loaded || ns->profile_ptr[profile])
1086 domain->profile = (u8) profile; 1092 domain->profile = (u8) profile;
1087 return 0; 1093 return 0;
1088 } 1094 }
1089 if (sscanf(data, "use_group %u\n", &profile) == 1 1095 if (sscanf(data, "use_group %u\n", &profile) == 1
1090 && profile < TOMOYO_MAX_ACL_GROUPS) { 1096 && profile < TOMOYO_MAX_ACL_GROUPS) {
1091 if (!is_delete) 1097 if (!is_delete)
1092 domain->group = (u8) profile; 1098 domain->group = (u8) profile;
1093 return 0; 1099 return 0;
1094 } 1100 }
1095 for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) { 1101 for (profile = 0; profile < TOMOYO_MAX_DOMAIN_INFO_FLAGS; profile++) {
1096 const char *cp = tomoyo_dif[profile]; 1102 const char *cp = tomoyo_dif[profile];
1097 if (strncmp(data, cp, strlen(cp) - 1)) 1103 if (strncmp(data, cp, strlen(cp) - 1))
1098 continue; 1104 continue;
1099 domain->flags[profile] = !is_delete; 1105 domain->flags[profile] = !is_delete;
1100 return 0; 1106 return 0;
1101 } 1107 }
1102 return tomoyo_write_domain2(ns, &domain->acl_info_list, data, 1108 return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
1103 is_delete); 1109 is_delete);
1104 } 1110 }
1105 1111
1106 /** 1112 /**
1107 * tomoyo_print_condition - Print condition part. 1113 * tomoyo_print_condition - Print condition part.
1108 * 1114 *
1109 * @head: Pointer to "struct tomoyo_io_buffer". 1115 * @head: Pointer to "struct tomoyo_io_buffer".
1110 * @cond: Pointer to "struct tomoyo_condition". 1116 * @cond: Pointer to "struct tomoyo_condition".
1111 * 1117 *
1112 * Returns true on success, false otherwise. 1118 * Returns true on success, false otherwise.
1113 */ 1119 */
1114 static bool tomoyo_print_condition(struct tomoyo_io_buffer *head, 1120 static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1115 const struct tomoyo_condition *cond) 1121 const struct tomoyo_condition *cond)
1116 { 1122 {
1117 switch (head->r.cond_step) { 1123 switch (head->r.cond_step) {
1118 case 0: 1124 case 0:
1119 head->r.cond_index = 0; 1125 head->r.cond_index = 0;
1120 head->r.cond_step++; 1126 head->r.cond_step++;
1121 /* fall through */ 1127 /* fall through */
1122 case 1: 1128 case 1:
1123 { 1129 {
1124 const u16 condc = cond->condc; 1130 const u16 condc = cond->condc;
1125 const struct tomoyo_condition_element *condp = 1131 const struct tomoyo_condition_element *condp =
1126 (typeof(condp)) (cond + 1); 1132 (typeof(condp)) (cond + 1);
1127 const struct tomoyo_number_union *numbers_p = 1133 const struct tomoyo_number_union *numbers_p =
1128 (typeof(numbers_p)) (condp + condc); 1134 (typeof(numbers_p)) (condp + condc);
1129 const struct tomoyo_name_union *names_p = 1135 const struct tomoyo_name_union *names_p =
1130 (typeof(names_p)) 1136 (typeof(names_p))
1131 (numbers_p + cond->numbers_count); 1137 (numbers_p + cond->numbers_count);
1132 const struct tomoyo_argv *argv = 1138 const struct tomoyo_argv *argv =
1133 (typeof(argv)) (names_p + cond->names_count); 1139 (typeof(argv)) (names_p + cond->names_count);
1134 const struct tomoyo_envp *envp = 1140 const struct tomoyo_envp *envp =
1135 (typeof(envp)) (argv + cond->argc); 1141 (typeof(envp)) (argv + cond->argc);
1136 u16 skip; 1142 u16 skip;
1137 for (skip = 0; skip < head->r.cond_index; skip++) { 1143 for (skip = 0; skip < head->r.cond_index; skip++) {
1138 const u8 left = condp->left; 1144 const u8 left = condp->left;
1139 const u8 right = condp->right; 1145 const u8 right = condp->right;
1140 condp++; 1146 condp++;
1141 switch (left) { 1147 switch (left) {
1142 case TOMOYO_ARGV_ENTRY: 1148 case TOMOYO_ARGV_ENTRY:
1143 argv++; 1149 argv++;
1144 continue; 1150 continue;
1145 case TOMOYO_ENVP_ENTRY: 1151 case TOMOYO_ENVP_ENTRY:
1146 envp++; 1152 envp++;
1147 continue; 1153 continue;
1148 case TOMOYO_NUMBER_UNION: 1154 case TOMOYO_NUMBER_UNION:
1149 numbers_p++; 1155 numbers_p++;
1150 break; 1156 break;
1151 } 1157 }
1152 switch (right) { 1158 switch (right) {
1153 case TOMOYO_NAME_UNION: 1159 case TOMOYO_NAME_UNION:
1154 names_p++; 1160 names_p++;
1155 break; 1161 break;
1156 case TOMOYO_NUMBER_UNION: 1162 case TOMOYO_NUMBER_UNION:
1157 numbers_p++; 1163 numbers_p++;
1158 break; 1164 break;
1159 } 1165 }
1160 } 1166 }
1161 while (head->r.cond_index < condc) { 1167 while (head->r.cond_index < condc) {
1162 const u8 match = condp->equals; 1168 const u8 match = condp->equals;
1163 const u8 left = condp->left; 1169 const u8 left = condp->left;
1164 const u8 right = condp->right; 1170 const u8 right = condp->right;
1165 if (!tomoyo_flush(head)) 1171 if (!tomoyo_flush(head))
1166 return false; 1172 return false;
1167 condp++; 1173 condp++;
1168 head->r.cond_index++; 1174 head->r.cond_index++;
1169 tomoyo_set_space(head); 1175 tomoyo_set_space(head);
1170 switch (left) { 1176 switch (left) {
1171 case TOMOYO_ARGV_ENTRY: 1177 case TOMOYO_ARGV_ENTRY:
1172 tomoyo_io_printf(head, 1178 tomoyo_io_printf(head,
1173 "exec.argv[%lu]%s=\"", 1179 "exec.argv[%lu]%s=\"",
1174 argv->index, argv-> 1180 argv->index, argv->
1175 is_not ? "!" : ""); 1181 is_not ? "!" : "");
1176 tomoyo_set_string(head, 1182 tomoyo_set_string(head,
1177 argv->value->name); 1183 argv->value->name);
1178 tomoyo_set_string(head, "\""); 1184 tomoyo_set_string(head, "\"");
1179 argv++; 1185 argv++;
1180 continue; 1186 continue;
1181 case TOMOYO_ENVP_ENTRY: 1187 case TOMOYO_ENVP_ENTRY:
1182 tomoyo_set_string(head, 1188 tomoyo_set_string(head,
1183 "exec.envp[\""); 1189 "exec.envp[\"");
1184 tomoyo_set_string(head, 1190 tomoyo_set_string(head,
1185 envp->name->name); 1191 envp->name->name);
1186 tomoyo_io_printf(head, "\"]%s=", envp-> 1192 tomoyo_io_printf(head, "\"]%s=", envp->
1187 is_not ? "!" : ""); 1193 is_not ? "!" : "");
1188 if (envp->value) { 1194 if (envp->value) {
1189 tomoyo_set_string(head, "\""); 1195 tomoyo_set_string(head, "\"");
1190 tomoyo_set_string(head, envp-> 1196 tomoyo_set_string(head, envp->
1191 value->name); 1197 value->name);
1192 tomoyo_set_string(head, "\""); 1198 tomoyo_set_string(head, "\"");
1193 } else { 1199 } else {
1194 tomoyo_set_string(head, 1200 tomoyo_set_string(head,
1195 "NULL"); 1201 "NULL");
1196 } 1202 }
1197 envp++; 1203 envp++;
1198 continue; 1204 continue;
1199 case TOMOYO_NUMBER_UNION: 1205 case TOMOYO_NUMBER_UNION:
1200 tomoyo_print_number_union_nospace 1206 tomoyo_print_number_union_nospace
1201 (head, numbers_p++); 1207 (head, numbers_p++);
1202 break; 1208 break;
1203 default: 1209 default:
1204 tomoyo_set_string(head, 1210 tomoyo_set_string(head,
1205 tomoyo_condition_keyword[left]); 1211 tomoyo_condition_keyword[left]);
1206 break; 1212 break;
1207 } 1213 }
1208 tomoyo_set_string(head, match ? "=" : "!="); 1214 tomoyo_set_string(head, match ? "=" : "!=");
1209 switch (right) { 1215 switch (right) {
1210 case TOMOYO_NAME_UNION: 1216 case TOMOYO_NAME_UNION:
1211 tomoyo_print_name_union_quoted 1217 tomoyo_print_name_union_quoted
1212 (head, names_p++); 1218 (head, names_p++);
1213 break; 1219 break;
1214 case TOMOYO_NUMBER_UNION: 1220 case TOMOYO_NUMBER_UNION:
1215 tomoyo_print_number_union_nospace 1221 tomoyo_print_number_union_nospace
1216 (head, numbers_p++); 1222 (head, numbers_p++);
1217 break; 1223 break;
1218 default: 1224 default:
1219 tomoyo_set_string(head, 1225 tomoyo_set_string(head,
1220 tomoyo_condition_keyword[right]); 1226 tomoyo_condition_keyword[right]);
1221 break; 1227 break;
1222 } 1228 }
1223 } 1229 }
1224 } 1230 }
1225 head->r.cond_step++; 1231 head->r.cond_step++;
1226 /* fall through */ 1232 /* fall through */
1227 case 2: 1233 case 2:
1228 if (!tomoyo_flush(head)) 1234 if (!tomoyo_flush(head))
1229 break; 1235 break;
1230 head->r.cond_step++; 1236 head->r.cond_step++;
1231 /* fall through */ 1237 /* fall through */
1232 case 3: 1238 case 3:
1233 tomoyo_set_lf(head); 1239 tomoyo_set_lf(head);
1234 return true; 1240 return true;
1235 } 1241 }
1236 return false; 1242 return false;
1237 } 1243 }
1238 1244
1239 /** 1245 /**
1240 * tomoyo_set_group - Print "acl_group " header keyword and category name. 1246 * tomoyo_set_group - Print "acl_group " header keyword and category name.
1241 * 1247 *
1242 * @head: Pointer to "struct tomoyo_io_buffer". 1248 * @head: Pointer to "struct tomoyo_io_buffer".
1243 * @category: Category name. 1249 * @category: Category name.
1244 * 1250 *
1245 * Returns nothing. 1251 * Returns nothing.
1246 */ 1252 */
1247 static void tomoyo_set_group(struct tomoyo_io_buffer *head, 1253 static void tomoyo_set_group(struct tomoyo_io_buffer *head,
1248 const char *category) 1254 const char *category)
1249 { 1255 {
1250 if (head->type == TOMOYO_EXCEPTIONPOLICY) { 1256 if (head->type == TOMOYO_EXCEPTIONPOLICY) {
1251 tomoyo_print_namespace(head); 1257 tomoyo_print_namespace(head);
1252 tomoyo_io_printf(head, "acl_group %u ", 1258 tomoyo_io_printf(head, "acl_group %u ",
1253 head->r.acl_group_index); 1259 head->r.acl_group_index);
1254 } 1260 }
1255 tomoyo_set_string(head, category); 1261 tomoyo_set_string(head, category);
1256 } 1262 }
1257 1263
1258 /** 1264 /**
1259 * tomoyo_print_entry - Print an ACL entry. 1265 * tomoyo_print_entry - Print an ACL entry.
1260 * 1266 *
1261 * @head: Pointer to "struct tomoyo_io_buffer". 1267 * @head: Pointer to "struct tomoyo_io_buffer".
1262 * @acl: Pointer to an ACL entry. 1268 * @acl: Pointer to an ACL entry.
1263 * 1269 *
1264 * Returns true on success, false otherwise. 1270 * Returns true on success, false otherwise.
1265 */ 1271 */
1266 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1272 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1267 struct tomoyo_acl_info *acl) 1273 struct tomoyo_acl_info *acl)
1268 { 1274 {
1269 const u8 acl_type = acl->type; 1275 const u8 acl_type = acl->type;
1270 bool first = true; 1276 bool first = true;
1271 u8 bit; 1277 u8 bit;
1272 1278
1273 if (head->r.print_cond_part) 1279 if (head->r.print_cond_part)
1274 goto print_cond_part; 1280 goto print_cond_part;
1275 if (acl->is_deleted) 1281 if (acl->is_deleted)
1276 return true; 1282 return true;
1277 if (!tomoyo_flush(head)) 1283 if (!tomoyo_flush(head))
1278 return false; 1284 return false;
1279 else if (acl_type == TOMOYO_TYPE_PATH_ACL) { 1285 else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
1280 struct tomoyo_path_acl *ptr = 1286 struct tomoyo_path_acl *ptr =
1281 container_of(acl, typeof(*ptr), head); 1287 container_of(acl, typeof(*ptr), head);
1282 const u16 perm = ptr->perm; 1288 const u16 perm = ptr->perm;
1283 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { 1289 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
1284 if (!(perm & (1 << bit))) 1290 if (!(perm & (1 << bit)))
1285 continue; 1291 continue;
1286 if (head->r.print_transition_related_only && 1292 if (head->r.print_transition_related_only &&
1287 bit != TOMOYO_TYPE_EXECUTE) 1293 bit != TOMOYO_TYPE_EXECUTE)
1288 continue; 1294 continue;
1289 if (first) { 1295 if (first) {
1290 tomoyo_set_group(head, "file "); 1296 tomoyo_set_group(head, "file ");
1291 first = false; 1297 first = false;
1292 } else { 1298 } else {
1293 tomoyo_set_slash(head); 1299 tomoyo_set_slash(head);
1294 } 1300 }
1295 tomoyo_set_string(head, tomoyo_path_keyword[bit]); 1301 tomoyo_set_string(head, tomoyo_path_keyword[bit]);
1296 } 1302 }
1297 if (first) 1303 if (first)
1298 return true; 1304 return true;
1299 tomoyo_print_name_union(head, &ptr->name); 1305 tomoyo_print_name_union(head, &ptr->name);
1300 } else if (head->r.print_transition_related_only) { 1306 } else if (head->r.print_transition_related_only) {
1301 return true; 1307 return true;
1302 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) { 1308 } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
1303 struct tomoyo_path2_acl *ptr = 1309 struct tomoyo_path2_acl *ptr =
1304 container_of(acl, typeof(*ptr), head); 1310 container_of(acl, typeof(*ptr), head);
1305 const u8 perm = ptr->perm; 1311 const u8 perm = ptr->perm;
1306 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { 1312 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
1307 if (!(perm & (1 << bit))) 1313 if (!(perm & (1 << bit)))
1308 continue; 1314 continue;
1309 if (first) { 1315 if (first) {
1310 tomoyo_set_group(head, "file "); 1316 tomoyo_set_group(head, "file ");
1311 first = false; 1317 first = false;
1312 } else { 1318 } else {
1313 tomoyo_set_slash(head); 1319 tomoyo_set_slash(head);
1314 } 1320 }
1315 tomoyo_set_string(head, tomoyo_mac_keywords 1321 tomoyo_set_string(head, tomoyo_mac_keywords
1316 [tomoyo_pp2mac[bit]]); 1322 [tomoyo_pp2mac[bit]]);
1317 } 1323 }
1318 if (first) 1324 if (first)
1319 return true; 1325 return true;
1320 tomoyo_print_name_union(head, &ptr->name1); 1326 tomoyo_print_name_union(head, &ptr->name1);
1321 tomoyo_print_name_union(head, &ptr->name2); 1327 tomoyo_print_name_union(head, &ptr->name2);
1322 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) { 1328 } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
1323 struct tomoyo_path_number_acl *ptr = 1329 struct tomoyo_path_number_acl *ptr =
1324 container_of(acl, typeof(*ptr), head); 1330 container_of(acl, typeof(*ptr), head);
1325 const u8 perm = ptr->perm; 1331 const u8 perm = ptr->perm;
1326 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) { 1332 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) {
1327 if (!(perm & (1 << bit))) 1333 if (!(perm & (1 << bit)))
1328 continue; 1334 continue;
1329 if (first) { 1335 if (first) {
1330 tomoyo_set_group(head, "file "); 1336 tomoyo_set_group(head, "file ");
1331 first = false; 1337 first = false;
1332 } else { 1338 } else {
1333 tomoyo_set_slash(head); 1339 tomoyo_set_slash(head);
1334 } 1340 }
1335 tomoyo_set_string(head, tomoyo_mac_keywords 1341 tomoyo_set_string(head, tomoyo_mac_keywords
1336 [tomoyo_pn2mac[bit]]); 1342 [tomoyo_pn2mac[bit]]);
1337 } 1343 }
1338 if (first) 1344 if (first)
1339 return true; 1345 return true;
1340 tomoyo_print_name_union(head, &ptr->name); 1346 tomoyo_print_name_union(head, &ptr->name);
1341 tomoyo_print_number_union(head, &ptr->number); 1347 tomoyo_print_number_union(head, &ptr->number);
1342 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) { 1348 } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
1343 struct tomoyo_mkdev_acl *ptr = 1349 struct tomoyo_mkdev_acl *ptr =
1344 container_of(acl, typeof(*ptr), head); 1350 container_of(acl, typeof(*ptr), head);
1345 const u8 perm = ptr->perm; 1351 const u8 perm = ptr->perm;
1346 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) { 1352 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) {
1347 if (!(perm & (1 << bit))) 1353 if (!(perm & (1 << bit)))
1348 continue; 1354 continue;
1349 if (first) { 1355 if (first) {
1350 tomoyo_set_group(head, "file "); 1356 tomoyo_set_group(head, "file ");
1351 first = false; 1357 first = false;
1352 } else { 1358 } else {
1353 tomoyo_set_slash(head); 1359 tomoyo_set_slash(head);
1354 } 1360 }
1355 tomoyo_set_string(head, tomoyo_mac_keywords 1361 tomoyo_set_string(head, tomoyo_mac_keywords
1356 [tomoyo_pnnn2mac[bit]]); 1362 [tomoyo_pnnn2mac[bit]]);
1357 } 1363 }
1358 if (first) 1364 if (first)
1359 return true; 1365 return true;
1360 tomoyo_print_name_union(head, &ptr->name); 1366 tomoyo_print_name_union(head, &ptr->name);
1361 tomoyo_print_number_union(head, &ptr->mode); 1367 tomoyo_print_number_union(head, &ptr->mode);
1362 tomoyo_print_number_union(head, &ptr->major); 1368 tomoyo_print_number_union(head, &ptr->major);
1363 tomoyo_print_number_union(head, &ptr->minor); 1369 tomoyo_print_number_union(head, &ptr->minor);
1364 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) { 1370 } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
1365 struct tomoyo_mount_acl *ptr = 1371 struct tomoyo_mount_acl *ptr =
1366 container_of(acl, typeof(*ptr), head); 1372 container_of(acl, typeof(*ptr), head);
1367 tomoyo_set_group(head, "file mount"); 1373 tomoyo_set_group(head, "file mount");
1368 tomoyo_print_name_union(head, &ptr->dev_name); 1374 tomoyo_print_name_union(head, &ptr->dev_name);
1369 tomoyo_print_name_union(head, &ptr->dir_name); 1375 tomoyo_print_name_union(head, &ptr->dir_name);
1370 tomoyo_print_name_union(head, &ptr->fs_type); 1376 tomoyo_print_name_union(head, &ptr->fs_type);
1371 tomoyo_print_number_union(head, &ptr->flags); 1377 tomoyo_print_number_union(head, &ptr->flags);
1372 } 1378 }
1373 if (acl->cond) { 1379 if (acl->cond) {
1374 head->r.print_cond_part = true; 1380 head->r.print_cond_part = true;
1375 head->r.cond_step = 0; 1381 head->r.cond_step = 0;
1376 if (!tomoyo_flush(head)) 1382 if (!tomoyo_flush(head))
1377 return false; 1383 return false;
1378 print_cond_part: 1384 print_cond_part:
1379 if (!tomoyo_print_condition(head, acl->cond)) 1385 if (!tomoyo_print_condition(head, acl->cond))
1380 return false; 1386 return false;
1381 head->r.print_cond_part = false; 1387 head->r.print_cond_part = false;
1382 } else { 1388 } else {
1383 tomoyo_set_lf(head); 1389 tomoyo_set_lf(head);
1384 } 1390 }
1385 return true; 1391 return true;
1386 } 1392 }
1387 1393
1388 /** 1394 /**
1389 * tomoyo_read_domain2 - Read domain policy. 1395 * tomoyo_read_domain2 - Read domain policy.
1390 * 1396 *
1391 * @head: Pointer to "struct tomoyo_io_buffer". 1397 * @head: Pointer to "struct tomoyo_io_buffer".
1392 * @list: Pointer to "struct list_head". 1398 * @list: Pointer to "struct list_head".
1393 * 1399 *
1394 * Caller holds tomoyo_read_lock(). 1400 * Caller holds tomoyo_read_lock().
1395 * 1401 *
1396 * Returns true on success, false otherwise. 1402 * Returns true on success, false otherwise.
1397 */ 1403 */
1398 static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head, 1404 static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
1399 struct list_head *list) 1405 struct list_head *list)
1400 { 1406 {
1401 list_for_each_cookie(head->r.acl, list) { 1407 list_for_each_cookie(head->r.acl, list) {
1402 struct tomoyo_acl_info *ptr = 1408 struct tomoyo_acl_info *ptr =
1403 list_entry(head->r.acl, typeof(*ptr), list); 1409 list_entry(head->r.acl, typeof(*ptr), list);
1404 if (!tomoyo_print_entry(head, ptr)) 1410 if (!tomoyo_print_entry(head, ptr))
1405 return false; 1411 return false;
1406 } 1412 }
1407 head->r.acl = NULL; 1413 head->r.acl = NULL;
1408 return true; 1414 return true;
1409 } 1415 }
1410 1416
1411 /** 1417 /**
1412 * tomoyo_read_domain - Read domain policy. 1418 * tomoyo_read_domain - Read domain policy.
1413 * 1419 *
1414 * @head: Pointer to "struct tomoyo_io_buffer". 1420 * @head: Pointer to "struct tomoyo_io_buffer".
1415 * 1421 *
1416 * Caller holds tomoyo_read_lock(). 1422 * Caller holds tomoyo_read_lock().
1417 */ 1423 */
1418 static void tomoyo_read_domain(struct tomoyo_io_buffer *head) 1424 static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1419 { 1425 {
1420 if (head->r.eof) 1426 if (head->r.eof)
1421 return; 1427 return;
1422 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) { 1428 list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
1423 struct tomoyo_domain_info *domain = 1429 struct tomoyo_domain_info *domain =
1424 list_entry(head->r.domain, typeof(*domain), list); 1430 list_entry(head->r.domain, typeof(*domain), list);
1425 switch (head->r.step) { 1431 switch (head->r.step) {
1426 u8 i; 1432 u8 i;
1427 case 0: 1433 case 0:
1428 if (domain->is_deleted && 1434 if (domain->is_deleted &&
1429 !head->r.print_this_domain_only) 1435 !head->r.print_this_domain_only)
1430 continue; 1436 continue;
1431 /* Print domainname and flags. */ 1437 /* Print domainname and flags. */
1432 tomoyo_set_string(head, domain->domainname->name); 1438 tomoyo_set_string(head, domain->domainname->name);
1433 tomoyo_set_lf(head); 1439 tomoyo_set_lf(head);
1434 tomoyo_io_printf(head, "use_profile %u\n", 1440 tomoyo_io_printf(head, "use_profile %u\n",
1435 domain->profile); 1441 domain->profile);
1436 tomoyo_io_printf(head, "use_group %u\n", 1442 tomoyo_io_printf(head, "use_group %u\n",
1437 domain->group); 1443 domain->group);
1438 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++) 1444 for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
1439 if (domain->flags[i]) 1445 if (domain->flags[i])
1440 tomoyo_set_string(head, tomoyo_dif[i]); 1446 tomoyo_set_string(head, tomoyo_dif[i]);
1441 head->r.step++; 1447 head->r.step++;
1442 tomoyo_set_lf(head); 1448 tomoyo_set_lf(head);
1443 /* fall through */ 1449 /* fall through */
1444 case 1: 1450 case 1:
1445 if (!tomoyo_read_domain2(head, &domain->acl_info_list)) 1451 if (!tomoyo_read_domain2(head, &domain->acl_info_list))
1446 return; 1452 return;
1447 head->r.step++; 1453 head->r.step++;
1448 if (!tomoyo_set_lf(head)) 1454 if (!tomoyo_set_lf(head))
1449 return; 1455 return;
1450 /* fall through */ 1456 /* fall through */
1451 case 2: 1457 case 2:
1452 head->r.step = 0; 1458 head->r.step = 0;
1453 if (head->r.print_this_domain_only) 1459 if (head->r.print_this_domain_only)
1454 goto done; 1460 goto done;
1455 } 1461 }
1456 } 1462 }
1457 done: 1463 done:
1458 head->r.eof = true; 1464 head->r.eof = true;
1459 } 1465 }
1460 1466
1461 /** 1467 /**
1462 * tomoyo_write_pid: Specify PID to obtain domainname. 1468 * tomoyo_write_pid: Specify PID to obtain domainname.
1463 * 1469 *
1464 * @head: Pointer to "struct tomoyo_io_buffer". 1470 * @head: Pointer to "struct tomoyo_io_buffer".
1465 * 1471 *
1466 * Returns 0. 1472 * Returns 0.
1467 */ 1473 */
1468 static int tomoyo_write_pid(struct tomoyo_io_buffer *head) 1474 static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1469 { 1475 {
1470 head->r.eof = false; 1476 head->r.eof = false;
1471 return 0; 1477 return 0;
1472 } 1478 }
1473 1479
1474 /** 1480 /**
1475 * tomoyo_read_pid - Get domainname of the specified PID. 1481 * tomoyo_read_pid - Get domainname of the specified PID.
1476 * 1482 *
1477 * @head: Pointer to "struct tomoyo_io_buffer". 1483 * @head: Pointer to "struct tomoyo_io_buffer".
1478 * 1484 *
1479 * Returns the domainname which the specified PID is in on success, 1485 * Returns the domainname which the specified PID is in on success,
1480 * empty string otherwise. 1486 * empty string otherwise.
1481 * The PID is specified by tomoyo_write_pid() so that the user can obtain 1487 * The PID is specified by tomoyo_write_pid() so that the user can obtain
1482 * using read()/write() interface rather than sysctl() interface. 1488 * using read()/write() interface rather than sysctl() interface.
1483 */ 1489 */
1484 static void tomoyo_read_pid(struct tomoyo_io_buffer *head) 1490 static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1485 { 1491 {
1486 char *buf = head->write_buf; 1492 char *buf = head->write_buf;
1487 bool global_pid = false; 1493 bool global_pid = false;
1488 unsigned int pid; 1494 unsigned int pid;
1489 struct task_struct *p; 1495 struct task_struct *p;
1490 struct tomoyo_domain_info *domain = NULL; 1496 struct tomoyo_domain_info *domain = NULL;
1491 1497
1492 /* Accessing write_buf is safe because head->io_sem is held. */ 1498 /* Accessing write_buf is safe because head->io_sem is held. */
1493 if (!buf) { 1499 if (!buf) {
1494 head->r.eof = true; 1500 head->r.eof = true;
1495 return; /* Do nothing if open(O_RDONLY). */ 1501 return; /* Do nothing if open(O_RDONLY). */
1496 } 1502 }
1497 if (head->r.w_pos || head->r.eof) 1503 if (head->r.w_pos || head->r.eof)
1498 return; 1504 return;
1499 head->r.eof = true; 1505 head->r.eof = true;
1500 if (tomoyo_str_starts(&buf, "global-pid ")) 1506 if (tomoyo_str_starts(&buf, "global-pid "))
1501 global_pid = true; 1507 global_pid = true;
1502 pid = (unsigned int) simple_strtoul(buf, NULL, 10); 1508 pid = (unsigned int) simple_strtoul(buf, NULL, 10);
1503 rcu_read_lock(); 1509 rcu_read_lock();
1504 read_lock(&tasklist_lock); 1510 read_lock(&tasklist_lock);
1505 if (global_pid) 1511 if (global_pid)
1506 p = find_task_by_pid_ns(pid, &init_pid_ns); 1512 p = find_task_by_pid_ns(pid, &init_pid_ns);
1507 else 1513 else
1508 p = find_task_by_vpid(pid); 1514 p = find_task_by_vpid(pid);
1509 if (p) 1515 if (p)
1510 domain = tomoyo_real_domain(p); 1516 domain = tomoyo_real_domain(p);
1511 read_unlock(&tasklist_lock); 1517 read_unlock(&tasklist_lock);
1512 rcu_read_unlock(); 1518 rcu_read_unlock();
1513 if (!domain) 1519 if (!domain)
1514 return; 1520 return;
1515 tomoyo_io_printf(head, "%u %u ", pid, domain->profile); 1521 tomoyo_io_printf(head, "%u %u ", pid, domain->profile);
1516 tomoyo_set_string(head, domain->domainname->name); 1522 tomoyo_set_string(head, domain->domainname->name);
1517 } 1523 }
1518 1524
1525 /* String table for domain transition control keywords. */
1519 static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = { 1526 static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1520 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ", 1527 [TOMOYO_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ",
1521 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ", 1528 [TOMOYO_TRANSITION_CONTROL_RESET] = "reset_domain ",
1522 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ", 1529 [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1523 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ", 1530 [TOMOYO_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ",
1524 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ", 1531 [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ",
1525 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ", 1532 [TOMOYO_TRANSITION_CONTROL_KEEP] = "keep_domain ",
1526 }; 1533 };
1527 1534
1535 /* String table for grouping keywords. */
1528 static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { 1536 static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1529 [TOMOYO_PATH_GROUP] = "path_group ", 1537 [TOMOYO_PATH_GROUP] = "path_group ",
1530 [TOMOYO_NUMBER_GROUP] = "number_group ", 1538 [TOMOYO_NUMBER_GROUP] = "number_group ",
1531 }; 1539 };
1532 1540
1533 /** 1541 /**
1534 * tomoyo_write_exception - Write exception policy. 1542 * tomoyo_write_exception - Write exception policy.
1535 * 1543 *
1536 * @head: Pointer to "struct tomoyo_io_buffer". 1544 * @head: Pointer to "struct tomoyo_io_buffer".
1537 * 1545 *
1538 * Returns 0 on success, negative value otherwise. 1546 * Returns 0 on success, negative value otherwise.
1539 * 1547 *
1540 * Caller holds tomoyo_read_lock(). 1548 * Caller holds tomoyo_read_lock().
1541 */ 1549 */
1542 static int tomoyo_write_exception(struct tomoyo_io_buffer *head) 1550 static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1543 { 1551 {
1544 const bool is_delete = head->w.is_delete; 1552 const bool is_delete = head->w.is_delete;
1545 struct tomoyo_acl_param param = { 1553 struct tomoyo_acl_param param = {
1546 .ns = head->w.ns, 1554 .ns = head->w.ns,
1547 .is_delete = is_delete, 1555 .is_delete = is_delete,
1548 .data = head->write_buf, 1556 .data = head->write_buf,
1549 }; 1557 };
1550 u8 i; 1558 u8 i;
1551 if (tomoyo_str_starts(&param.data, "aggregator ")) 1559 if (tomoyo_str_starts(&param.data, "aggregator "))
1552 return tomoyo_write_aggregator(&param); 1560 return tomoyo_write_aggregator(&param);
1553 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) 1561 for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
1554 if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i])) 1562 if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
1555 return tomoyo_write_transition_control(&param, i); 1563 return tomoyo_write_transition_control(&param, i);
1556 for (i = 0; i < TOMOYO_MAX_GROUP; i++) 1564 for (i = 0; i < TOMOYO_MAX_GROUP; i++)
1557 if (tomoyo_str_starts(&param.data, tomoyo_group_name[i])) 1565 if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
1558 return tomoyo_write_group(&param, i); 1566 return tomoyo_write_group(&param, i);
1559 if (tomoyo_str_starts(&param.data, "acl_group ")) { 1567 if (tomoyo_str_starts(&param.data, "acl_group ")) {
1560 unsigned int group; 1568 unsigned int group;
1561 char *data; 1569 char *data;
1562 group = simple_strtoul(param.data, &data, 10); 1570 group = simple_strtoul(param.data, &data, 10);
1563 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ') 1571 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1564 return tomoyo_write_domain2 1572 return tomoyo_write_domain2
1565 (head->w.ns, &head->w.ns->acl_group[group], 1573 (head->w.ns, &head->w.ns->acl_group[group],
1566 data, is_delete); 1574 data, is_delete);
1567 } 1575 }
1568 return -EINVAL; 1576 return -EINVAL;
1569 } 1577 }
1570 1578
1571 /** 1579 /**
1572 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 1580 * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
1573 * 1581 *
1574 * @head: Pointer to "struct tomoyo_io_buffer". 1582 * @head: Pointer to "struct tomoyo_io_buffer".
1575 * @idx: Index number. 1583 * @idx: Index number.
1576 * 1584 *
1577 * Returns true on success, false otherwise. 1585 * Returns true on success, false otherwise.
1578 * 1586 *
1579 * Caller holds tomoyo_read_lock(). 1587 * Caller holds tomoyo_read_lock().
1580 */ 1588 */
1581 static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) 1589 static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1582 { 1590 {
1583 struct tomoyo_policy_namespace *ns = 1591 struct tomoyo_policy_namespace *ns =
1584 container_of(head->r.ns, typeof(*ns), namespace_list); 1592 container_of(head->r.ns, typeof(*ns), namespace_list);
1585 struct list_head *list = &ns->group_list[idx]; 1593 struct list_head *list = &ns->group_list[idx];
1586 list_for_each_cookie(head->r.group, list) { 1594 list_for_each_cookie(head->r.group, list) {
1587 struct tomoyo_group *group = 1595 struct tomoyo_group *group =
1588 list_entry(head->r.group, typeof(*group), head.list); 1596 list_entry(head->r.group, typeof(*group), head.list);
1589 list_for_each_cookie(head->r.acl, &group->member_list) { 1597 list_for_each_cookie(head->r.acl, &group->member_list) {
1590 struct tomoyo_acl_head *ptr = 1598 struct tomoyo_acl_head *ptr =
1591 list_entry(head->r.acl, typeof(*ptr), list); 1599 list_entry(head->r.acl, typeof(*ptr), list);
1592 if (ptr->is_deleted) 1600 if (ptr->is_deleted)
1593 continue; 1601 continue;
1594 if (!tomoyo_flush(head)) 1602 if (!tomoyo_flush(head))
1595 return false; 1603 return false;
1596 tomoyo_print_namespace(head); 1604 tomoyo_print_namespace(head);
1597 tomoyo_set_string(head, tomoyo_group_name[idx]); 1605 tomoyo_set_string(head, tomoyo_group_name[idx]);
1598 tomoyo_set_string(head, group->group_name->name); 1606 tomoyo_set_string(head, group->group_name->name);
1599 if (idx == TOMOYO_PATH_GROUP) { 1607 if (idx == TOMOYO_PATH_GROUP) {
1600 tomoyo_set_space(head); 1608 tomoyo_set_space(head);
1601 tomoyo_set_string(head, container_of 1609 tomoyo_set_string(head, container_of
1602 (ptr, struct tomoyo_path_group, 1610 (ptr, struct tomoyo_path_group,
1603 head)->member_name->name); 1611 head)->member_name->name);
1604 } else if (idx == TOMOYO_NUMBER_GROUP) { 1612 } else if (idx == TOMOYO_NUMBER_GROUP) {
1605 tomoyo_print_number_union(head, &container_of 1613 tomoyo_print_number_union(head, &container_of
1606 (ptr, 1614 (ptr,
1607 struct tomoyo_number_group, 1615 struct tomoyo_number_group,
1608 head)->number); 1616 head)->number);
1609 } 1617 }
1610 tomoyo_set_lf(head); 1618 tomoyo_set_lf(head);
1611 } 1619 }
1612 head->r.acl = NULL; 1620 head->r.acl = NULL;
1613 } 1621 }
1614 head->r.group = NULL; 1622 head->r.group = NULL;
1615 return true; 1623 return true;
1616 } 1624 }
1617 1625
1618 /** 1626 /**
1619 * tomoyo_read_policy - Read "struct tomoyo_..._entry" list. 1627 * tomoyo_read_policy - Read "struct tomoyo_..._entry" list.
1620 * 1628 *
1621 * @head: Pointer to "struct tomoyo_io_buffer". 1629 * @head: Pointer to "struct tomoyo_io_buffer".
1622 * @idx: Index number. 1630 * @idx: Index number.
1623 * 1631 *
1624 * Returns true on success, false otherwise. 1632 * Returns true on success, false otherwise.
1625 * 1633 *
1626 * Caller holds tomoyo_read_lock(). 1634 * Caller holds tomoyo_read_lock().
1627 */ 1635 */
1628 static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) 1636 static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1629 { 1637 {
1630 struct tomoyo_policy_namespace *ns = 1638 struct tomoyo_policy_namespace *ns =
1631 container_of(head->r.ns, typeof(*ns), namespace_list); 1639 container_of(head->r.ns, typeof(*ns), namespace_list);
1632 struct list_head *list = &ns->policy_list[idx]; 1640 struct list_head *list = &ns->policy_list[idx];
1633 list_for_each_cookie(head->r.acl, list) { 1641 list_for_each_cookie(head->r.acl, list) {
1634 struct tomoyo_acl_head *acl = 1642 struct tomoyo_acl_head *acl =
1635 container_of(head->r.acl, typeof(*acl), list); 1643 container_of(head->r.acl, typeof(*acl), list);
1636 if (acl->is_deleted) 1644 if (acl->is_deleted)
1637 continue; 1645 continue;
1638 if (!tomoyo_flush(head)) 1646 if (!tomoyo_flush(head))
1639 return false; 1647 return false;
1640 switch (idx) { 1648 switch (idx) {
1641 case TOMOYO_ID_TRANSITION_CONTROL: 1649 case TOMOYO_ID_TRANSITION_CONTROL:
1642 { 1650 {
1643 struct tomoyo_transition_control *ptr = 1651 struct tomoyo_transition_control *ptr =
1644 container_of(acl, typeof(*ptr), head); 1652 container_of(acl, typeof(*ptr), head);
1645 tomoyo_print_namespace(head); 1653 tomoyo_print_namespace(head);
1646 tomoyo_set_string(head, tomoyo_transition_type 1654 tomoyo_set_string(head, tomoyo_transition_type
1647 [ptr->type]); 1655 [ptr->type]);
1648 tomoyo_set_string(head, ptr->program ? 1656 tomoyo_set_string(head, ptr->program ?
1649 ptr->program->name : "any"); 1657 ptr->program->name : "any");
1650 tomoyo_set_string(head, " from "); 1658 tomoyo_set_string(head, " from ");
1651 tomoyo_set_string(head, ptr->domainname ? 1659 tomoyo_set_string(head, ptr->domainname ?
1652 ptr->domainname->name : 1660 ptr->domainname->name :
1653 "any"); 1661 "any");
1654 } 1662 }
1655 break; 1663 break;
1656 case TOMOYO_ID_AGGREGATOR: 1664 case TOMOYO_ID_AGGREGATOR:
1657 { 1665 {
1658 struct tomoyo_aggregator *ptr = 1666 struct tomoyo_aggregator *ptr =
1659 container_of(acl, typeof(*ptr), head); 1667 container_of(acl, typeof(*ptr), head);
1660 tomoyo_print_namespace(head); 1668 tomoyo_print_namespace(head);
1661 tomoyo_set_string(head, "aggregator "); 1669 tomoyo_set_string(head, "aggregator ");
1662 tomoyo_set_string(head, 1670 tomoyo_set_string(head,
1663 ptr->original_name->name); 1671 ptr->original_name->name);
1664 tomoyo_set_space(head); 1672 tomoyo_set_space(head);
1665 tomoyo_set_string(head, 1673 tomoyo_set_string(head,
1666 ptr->aggregated_name->name); 1674 ptr->aggregated_name->name);
1667 } 1675 }
1668 break; 1676 break;
1669 default: 1677 default:
1670 continue; 1678 continue;
1671 } 1679 }
1672 tomoyo_set_lf(head); 1680 tomoyo_set_lf(head);
1673 } 1681 }
1674 head->r.acl = NULL; 1682 head->r.acl = NULL;
1675 return true; 1683 return true;
1676 } 1684 }
1677 1685
1678 /** 1686 /**
1679 * tomoyo_read_exception - Read exception policy. 1687 * tomoyo_read_exception - Read exception policy.
1680 * 1688 *
1681 * @head: Pointer to "struct tomoyo_io_buffer". 1689 * @head: Pointer to "struct tomoyo_io_buffer".
1682 * 1690 *
1683 * Caller holds tomoyo_read_lock(). 1691 * Caller holds tomoyo_read_lock().
1684 */ 1692 */
1685 static void tomoyo_read_exception(struct tomoyo_io_buffer *head) 1693 static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1686 { 1694 {
1687 struct tomoyo_policy_namespace *ns = 1695 struct tomoyo_policy_namespace *ns =
1688 container_of(head->r.ns, typeof(*ns), namespace_list); 1696 container_of(head->r.ns, typeof(*ns), namespace_list);
1689 if (head->r.eof) 1697 if (head->r.eof)
1690 return; 1698 return;
1691 while (head->r.step < TOMOYO_MAX_POLICY && 1699 while (head->r.step < TOMOYO_MAX_POLICY &&
1692 tomoyo_read_policy(head, head->r.step)) 1700 tomoyo_read_policy(head, head->r.step))
1693 head->r.step++; 1701 head->r.step++;
1694 if (head->r.step < TOMOYO_MAX_POLICY) 1702 if (head->r.step < TOMOYO_MAX_POLICY)
1695 return; 1703 return;
1696 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP && 1704 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
1697 tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY)) 1705 tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY))
1698 head->r.step++; 1706 head->r.step++;
1699 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) 1707 if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1700 return; 1708 return;
1701 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP 1709 while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP
1702 + TOMOYO_MAX_ACL_GROUPS) { 1710 + TOMOYO_MAX_ACL_GROUPS) {
1703 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY 1711 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1704 - TOMOYO_MAX_GROUP; 1712 - TOMOYO_MAX_GROUP;
1705 if (!tomoyo_read_domain2(head, &ns->acl_group 1713 if (!tomoyo_read_domain2(head, &ns->acl_group
1706 [head->r.acl_group_index])) 1714 [head->r.acl_group_index]))
1707 return; 1715 return;
1708 head->r.step++; 1716 head->r.step++;
1709 } 1717 }
1710 head->r.eof = true; 1718 head->r.eof = true;
1711 } 1719 }
1712 1720
1713 /* Wait queue for kernel -> userspace notification. */ 1721 /* Wait queue for kernel -> userspace notification. */
1714 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait); 1722 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
1715 /* Wait queue for userspace -> kernel notification. */ 1723 /* Wait queue for userspace -> kernel notification. */
1716 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait); 1724 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait);
1717 1725
1718 /* Structure for query. */ 1726 /* Structure for query. */
1719 struct tomoyo_query { 1727 struct tomoyo_query {
1720 struct list_head list; 1728 struct list_head list;
1721 char *query; 1729 char *query;
1722 size_t query_len; 1730 size_t query_len;
1723 unsigned int serial; 1731 unsigned int serial;
1724 u8 timer; 1732 u8 timer;
1725 u8 answer; 1733 u8 answer;
1726 u8 retry; 1734 u8 retry;
1727 }; 1735 };
1728 1736
1729 /* The list for "struct tomoyo_query". */ 1737 /* The list for "struct tomoyo_query". */
1730 static LIST_HEAD(tomoyo_query_list); 1738 static LIST_HEAD(tomoyo_query_list);
1731 1739
1732 /* Lock for manipulating tomoyo_query_list. */ 1740 /* Lock for manipulating tomoyo_query_list. */
1733 static DEFINE_SPINLOCK(tomoyo_query_list_lock); 1741 static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1734 1742
1735 /* 1743 /*
1736 * Number of "struct file" referring /sys/kernel/security/tomoyo/query 1744 * Number of "struct file" referring /sys/kernel/security/tomoyo/query
1737 * interface. 1745 * interface.
1738 */ 1746 */
1739 static atomic_t tomoyo_query_observers = ATOMIC_INIT(0); 1747 static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1740 1748
1741 /** 1749 /**
1742 * tomoyo_truncate - Truncate a line. 1750 * tomoyo_truncate - Truncate a line.
1743 * 1751 *
1744 * @str: String to truncate. 1752 * @str: String to truncate.
1745 * 1753 *
1746 * Returns length of truncated @str. 1754 * Returns length of truncated @str.
1747 */ 1755 */
1748 static int tomoyo_truncate(char *str) 1756 static int tomoyo_truncate(char *str)
1749 { 1757 {
1750 char *start = str; 1758 char *start = str;
1751 while (*(unsigned char *) str > (unsigned char) ' ') 1759 while (*(unsigned char *) str > (unsigned char) ' ')
1752 str++; 1760 str++;
1753 *str = '\0'; 1761 *str = '\0';
1754 return strlen(start) + 1; 1762 return strlen(start) + 1;
1755 } 1763 }
1756 1764
1757 /** 1765 /**
1758 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode. 1766 * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1759 * 1767 *
1760 * @domain: Pointer to "struct tomoyo_domain_info". 1768 * @domain: Pointer to "struct tomoyo_domain_info".
1761 * @header: Lines containing ACL. 1769 * @header: Lines containing ACL.
1762 * 1770 *
1763 * Returns nothing. 1771 * Returns nothing.
1764 */ 1772 */
1765 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header) 1773 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1766 { 1774 {
1767 char *buffer; 1775 char *buffer;
1768 char *realpath = NULL; 1776 char *realpath = NULL;
1769 char *argv0 = NULL; 1777 char *argv0 = NULL;
1770 char *symlink = NULL; 1778 char *symlink = NULL;
1771 char *cp = strchr(header, '\n'); 1779 char *cp = strchr(header, '\n');
1772 int len; 1780 int len;
1773 if (!cp) 1781 if (!cp)
1774 return; 1782 return;
1775 cp = strchr(cp + 1, '\n'); 1783 cp = strchr(cp + 1, '\n');
1776 if (!cp) 1784 if (!cp)
1777 return; 1785 return;
1778 *cp++ = '\0'; 1786 *cp++ = '\0';
1779 len = strlen(cp) + 1; 1787 len = strlen(cp) + 1;
1780 /* strstr() will return NULL if ordering is wrong. */ 1788 /* strstr() will return NULL if ordering is wrong. */
1781 if (*cp == 'f') { 1789 if (*cp == 'f') {
1782 argv0 = strstr(header, " argv[]={ \""); 1790 argv0 = strstr(header, " argv[]={ \"");
1783 if (argv0) { 1791 if (argv0) {
1784 argv0 += 10; 1792 argv0 += 10;
1785 len += tomoyo_truncate(argv0) + 14; 1793 len += tomoyo_truncate(argv0) + 14;
1786 } 1794 }
1787 realpath = strstr(header, " exec={ realpath=\""); 1795 realpath = strstr(header, " exec={ realpath=\"");
1788 if (realpath) { 1796 if (realpath) {
1789 realpath += 8; 1797 realpath += 8;
1790 len += tomoyo_truncate(realpath) + 6; 1798 len += tomoyo_truncate(realpath) + 6;
1791 } 1799 }
1792 symlink = strstr(header, " symlink.target=\""); 1800 symlink = strstr(header, " symlink.target=\"");
1793 if (symlink) 1801 if (symlink)
1794 len += tomoyo_truncate(symlink + 1) + 1; 1802 len += tomoyo_truncate(symlink + 1) + 1;
1795 } 1803 }
1796 buffer = kmalloc(len, GFP_NOFS); 1804 buffer = kmalloc(len, GFP_NOFS);
1797 if (!buffer) 1805 if (!buffer)
1798 return; 1806 return;
1799 snprintf(buffer, len - 1, "%s", cp); 1807 snprintf(buffer, len - 1, "%s", cp);
1800 if (realpath) 1808 if (realpath)
1801 tomoyo_addprintf(buffer, len, " exec.%s", realpath); 1809 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
1802 if (argv0) 1810 if (argv0)
1803 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0); 1811 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
1804 if (symlink) 1812 if (symlink)
1805 tomoyo_addprintf(buffer, len, "%s", symlink); 1813 tomoyo_addprintf(buffer, len, "%s", symlink);
1806 tomoyo_normalize_line(buffer); 1814 tomoyo_normalize_line(buffer);
1807 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer, 1815 if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
1808 false)) 1816 false))
1809 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 1817 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
1810 kfree(buffer); 1818 kfree(buffer);
1811 } 1819 }
1812 1820
1813 /** 1821 /**
1814 * tomoyo_supervisor - Ask for the supervisor's decision. 1822 * tomoyo_supervisor - Ask for the supervisor's decision.
1815 * 1823 *
1816 * @r: Pointer to "struct tomoyo_request_info". 1824 * @r: Pointer to "struct tomoyo_request_info".
1817 * @fmt: The printf()'s format string, followed by parameters. 1825 * @fmt: The printf()'s format string, followed by parameters.
1818 * 1826 *
1819 * Returns 0 if the supervisor decided to permit the access request which 1827 * Returns 0 if the supervisor decided to permit the access request which
1820 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the 1828 * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
1821 * supervisor decided to retry the access request which violated the policy in 1829 * supervisor decided to retry the access request which violated the policy in
1822 * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise. 1830 * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
1823 */ 1831 */
1824 int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...) 1832 int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
1825 { 1833 {
1826 va_list args; 1834 va_list args;
1827 int error; 1835 int error;
1828 int len; 1836 int len;
1829 static unsigned int tomoyo_serial; 1837 static unsigned int tomoyo_serial;
1830 struct tomoyo_query entry = { }; 1838 struct tomoyo_query entry = { };
1831 bool quota_exceeded = false; 1839 bool quota_exceeded = false;
1832 va_start(args, fmt); 1840 va_start(args, fmt);
1833 len = vsnprintf((char *) &len, 1, fmt, args) + 1; 1841 len = vsnprintf((char *) &len, 1, fmt, args) + 1;
1834 va_end(args); 1842 va_end(args);
1835 /* Write /sys/kernel/security/tomoyo/audit. */ 1843 /* Write /sys/kernel/security/tomoyo/audit. */
1836 va_start(args, fmt); 1844 va_start(args, fmt);
1837 tomoyo_write_log2(r, len, fmt, args); 1845 tomoyo_write_log2(r, len, fmt, args);
1838 va_end(args); 1846 va_end(args);
1839 /* Nothing more to do if granted. */ 1847 /* Nothing more to do if granted. */
1840 if (r->granted) 1848 if (r->granted)
1841 return 0; 1849 return 0;
1842 if (r->mode) 1850 if (r->mode)
1843 tomoyo_update_stat(r->mode); 1851 tomoyo_update_stat(r->mode);
1844 switch (r->mode) { 1852 switch (r->mode) {
1845 case TOMOYO_CONFIG_ENFORCING: 1853 case TOMOYO_CONFIG_ENFORCING:
1846 error = -EPERM; 1854 error = -EPERM;
1847 if (atomic_read(&tomoyo_query_observers)) 1855 if (atomic_read(&tomoyo_query_observers))
1848 break; 1856 break;
1849 goto out; 1857 goto out;
1850 case TOMOYO_CONFIG_LEARNING: 1858 case TOMOYO_CONFIG_LEARNING:
1851 error = 0; 1859 error = 0;
1852 /* Check max_learning_entry parameter. */ 1860 /* Check max_learning_entry parameter. */
1853 if (tomoyo_domain_quota_is_ok(r)) 1861 if (tomoyo_domain_quota_is_ok(r))
1854 break; 1862 break;
1855 /* fall through */ 1863 /* fall through */
1856 default: 1864 default:
1857 return 0; 1865 return 0;
1858 } 1866 }
1859 /* Get message. */ 1867 /* Get message. */
1860 va_start(args, fmt); 1868 va_start(args, fmt);
1861 entry.query = tomoyo_init_log(r, len, fmt, args); 1869 entry.query = tomoyo_init_log(r, len, fmt, args);
1862 va_end(args); 1870 va_end(args);
1863 if (!entry.query) 1871 if (!entry.query)
1864 goto out; 1872 goto out;
1865 entry.query_len = strlen(entry.query) + 1; 1873 entry.query_len = strlen(entry.query) + 1;
1866 if (!error) { 1874 if (!error) {
1867 tomoyo_add_entry(r->domain, entry.query); 1875 tomoyo_add_entry(r->domain, entry.query);
1868 goto out; 1876 goto out;
1869 } 1877 }
1870 len = tomoyo_round2(entry.query_len); 1878 len = tomoyo_round2(entry.query_len);
1871 spin_lock(&tomoyo_query_list_lock); 1879 spin_lock(&tomoyo_query_list_lock);
1872 if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] && 1880 if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
1873 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len 1881 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
1874 >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) { 1882 >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
1875 quota_exceeded = true; 1883 quota_exceeded = true;
1876 } else { 1884 } else {
1877 entry.serial = tomoyo_serial++; 1885 entry.serial = tomoyo_serial++;
1878 entry.retry = r->retry; 1886 entry.retry = r->retry;
1879 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len; 1887 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
1880 list_add_tail(&entry.list, &tomoyo_query_list); 1888 list_add_tail(&entry.list, &tomoyo_query_list);
1881 } 1889 }
1882 spin_unlock(&tomoyo_query_list_lock); 1890 spin_unlock(&tomoyo_query_list_lock);
1883 if (quota_exceeded) 1891 if (quota_exceeded)
1884 goto out; 1892 goto out;
1885 /* Give 10 seconds for supervisor's opinion. */ 1893 /* Give 10 seconds for supervisor's opinion. */
1886 while (entry.timer < 10) { 1894 while (entry.timer < 10) {
1887 wake_up_all(&tomoyo_query_wait); 1895 wake_up_all(&tomoyo_query_wait);
1888 if (wait_event_interruptible_timeout 1896 if (wait_event_interruptible_timeout
1889 (tomoyo_answer_wait, entry.answer || 1897 (tomoyo_answer_wait, entry.answer ||
1890 !atomic_read(&tomoyo_query_observers), HZ)) 1898 !atomic_read(&tomoyo_query_observers), HZ))
1891 break; 1899 break;
1892 else 1900 else
1893 entry.timer++; 1901 entry.timer++;
1894 } 1902 }
1895 spin_lock(&tomoyo_query_list_lock); 1903 spin_lock(&tomoyo_query_list_lock);
1896 list_del(&entry.list); 1904 list_del(&entry.list);
1897 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len; 1905 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
1898 spin_unlock(&tomoyo_query_list_lock); 1906 spin_unlock(&tomoyo_query_list_lock);
1899 switch (entry.answer) { 1907 switch (entry.answer) {
1900 case 3: /* Asked to retry by administrator. */ 1908 case 3: /* Asked to retry by administrator. */
1901 error = TOMOYO_RETRY_REQUEST; 1909 error = TOMOYO_RETRY_REQUEST;
1902 r->retry++; 1910 r->retry++;
1903 break; 1911 break;
1904 case 1: 1912 case 1:
1905 /* Granted by administrator. */ 1913 /* Granted by administrator. */
1906 error = 0; 1914 error = 0;
1907 break; 1915 break;
1908 default: 1916 default:
1909 /* Timed out or rejected by administrator. */ 1917 /* Timed out or rejected by administrator. */
1910 break; 1918 break;
1911 } 1919 }
1912 out: 1920 out:
1913 kfree(entry.query); 1921 kfree(entry.query);
1914 return error; 1922 return error;
1915 } 1923 }
1916 1924
1917 /** 1925 /**
1918 * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query. 1926 * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
1919 * 1927 *
1920 * @file: Pointer to "struct file". 1928 * @file: Pointer to "struct file".
1921 * @wait: Pointer to "poll_table". 1929 * @wait: Pointer to "poll_table".
1922 * 1930 *
1923 * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise. 1931 * Returns POLLIN | POLLRDNORM when ready to read, 0 otherwise.
1924 * 1932 *
1925 * Waits for access requests which violated policy in enforcing mode. 1933 * Waits for access requests which violated policy in enforcing mode.
1926 */ 1934 */
1927 static int tomoyo_poll_query(struct file *file, poll_table *wait) 1935 static int tomoyo_poll_query(struct file *file, poll_table *wait)
1928 { 1936 {
1929 struct list_head *tmp; 1937 struct list_head *tmp;
1930 bool found = false; 1938 bool found = false;
1931 u8 i; 1939 u8 i;
1932 for (i = 0; i < 2; i++) { 1940 for (i = 0; i < 2; i++) {
1933 spin_lock(&tomoyo_query_list_lock); 1941 spin_lock(&tomoyo_query_list_lock);
1934 list_for_each(tmp, &tomoyo_query_list) { 1942 list_for_each(tmp, &tomoyo_query_list) {
1935 struct tomoyo_query *ptr = 1943 struct tomoyo_query *ptr =
1936 list_entry(tmp, typeof(*ptr), list); 1944 list_entry(tmp, typeof(*ptr), list);
1937 if (ptr->answer) 1945 if (ptr->answer)
1938 continue; 1946 continue;
1939 found = true; 1947 found = true;
1940 break; 1948 break;
1941 } 1949 }
1942 spin_unlock(&tomoyo_query_list_lock); 1950 spin_unlock(&tomoyo_query_list_lock);
1943 if (found) 1951 if (found)
1944 return POLLIN | POLLRDNORM; 1952 return POLLIN | POLLRDNORM;
1945 if (i) 1953 if (i)
1946 break; 1954 break;
1947 poll_wait(file, &tomoyo_query_wait, wait); 1955 poll_wait(file, &tomoyo_query_wait, wait);
1948 } 1956 }
1949 return 0; 1957 return 0;
1950 } 1958 }
1951 1959
1952 /** 1960 /**
1953 * tomoyo_read_query - Read access requests which violated policy in enforcing mode. 1961 * tomoyo_read_query - Read access requests which violated policy in enforcing mode.
1954 * 1962 *
1955 * @head: Pointer to "struct tomoyo_io_buffer". 1963 * @head: Pointer to "struct tomoyo_io_buffer".
1956 */ 1964 */
1957 static void tomoyo_read_query(struct tomoyo_io_buffer *head) 1965 static void tomoyo_read_query(struct tomoyo_io_buffer *head)
1958 { 1966 {
1959 struct list_head *tmp; 1967 struct list_head *tmp;
1960 unsigned int pos = 0; 1968 unsigned int pos = 0;
1961 size_t len = 0; 1969 size_t len = 0;
1962 char *buf; 1970 char *buf;
1963 if (head->r.w_pos) 1971 if (head->r.w_pos)
1964 return; 1972 return;
1965 if (head->read_buf) { 1973 if (head->read_buf) {
1966 kfree(head->read_buf); 1974 kfree(head->read_buf);
1967 head->read_buf = NULL; 1975 head->read_buf = NULL;
1968 } 1976 }
1969 spin_lock(&tomoyo_query_list_lock); 1977 spin_lock(&tomoyo_query_list_lock);
1970 list_for_each(tmp, &tomoyo_query_list) { 1978 list_for_each(tmp, &tomoyo_query_list) {
1971 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 1979 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
1972 if (ptr->answer) 1980 if (ptr->answer)
1973 continue; 1981 continue;
1974 if (pos++ != head->r.query_index) 1982 if (pos++ != head->r.query_index)
1975 continue; 1983 continue;
1976 len = ptr->query_len; 1984 len = ptr->query_len;
1977 break; 1985 break;
1978 } 1986 }
1979 spin_unlock(&tomoyo_query_list_lock); 1987 spin_unlock(&tomoyo_query_list_lock);
1980 if (!len) { 1988 if (!len) {
1981 head->r.query_index = 0; 1989 head->r.query_index = 0;
1982 return; 1990 return;
1983 } 1991 }
1984 buf = kzalloc(len + 32, GFP_NOFS); 1992 buf = kzalloc(len + 32, GFP_NOFS);
1985 if (!buf) 1993 if (!buf)
1986 return; 1994 return;
1987 pos = 0; 1995 pos = 0;
1988 spin_lock(&tomoyo_query_list_lock); 1996 spin_lock(&tomoyo_query_list_lock);
1989 list_for_each(tmp, &tomoyo_query_list) { 1997 list_for_each(tmp, &tomoyo_query_list) {
1990 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 1998 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
1991 if (ptr->answer) 1999 if (ptr->answer)
1992 continue; 2000 continue;
1993 if (pos++ != head->r.query_index) 2001 if (pos++ != head->r.query_index)
1994 continue; 2002 continue;
1995 /* 2003 /*
1996 * Some query can be skipped because tomoyo_query_list 2004 * Some query can be skipped because tomoyo_query_list
1997 * can change, but I don't care. 2005 * can change, but I don't care.
1998 */ 2006 */
1999 if (len == ptr->query_len) 2007 if (len == ptr->query_len)
2000 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial, 2008 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
2001 ptr->retry, ptr->query); 2009 ptr->retry, ptr->query);
2002 break; 2010 break;
2003 } 2011 }
2004 spin_unlock(&tomoyo_query_list_lock); 2012 spin_unlock(&tomoyo_query_list_lock);
2005 if (buf[0]) { 2013 if (buf[0]) {
2006 head->read_buf = buf; 2014 head->read_buf = buf;
2007 head->r.w[head->r.w_pos++] = buf; 2015 head->r.w[head->r.w_pos++] = buf;
2008 head->r.query_index++; 2016 head->r.query_index++;
2009 } else { 2017 } else {
2010 kfree(buf); 2018 kfree(buf);
2011 } 2019 }
2012 } 2020 }
2013 2021
2014 /** 2022 /**
2015 * tomoyo_write_answer - Write the supervisor's decision. 2023 * tomoyo_write_answer - Write the supervisor's decision.
2016 * 2024 *
2017 * @head: Pointer to "struct tomoyo_io_buffer". 2025 * @head: Pointer to "struct tomoyo_io_buffer".
2018 * 2026 *
2019 * Returns 0 on success, -EINVAL otherwise. 2027 * Returns 0 on success, -EINVAL otherwise.
2020 */ 2028 */
2021 static int tomoyo_write_answer(struct tomoyo_io_buffer *head) 2029 static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2022 { 2030 {
2023 char *data = head->write_buf; 2031 char *data = head->write_buf;
2024 struct list_head *tmp; 2032 struct list_head *tmp;
2025 unsigned int serial; 2033 unsigned int serial;
2026 unsigned int answer; 2034 unsigned int answer;
2027 spin_lock(&tomoyo_query_list_lock); 2035 spin_lock(&tomoyo_query_list_lock);
2028 list_for_each(tmp, &tomoyo_query_list) { 2036 list_for_each(tmp, &tomoyo_query_list) {
2029 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2037 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2030 ptr->timer = 0; 2038 ptr->timer = 0;
2031 } 2039 }
2032 spin_unlock(&tomoyo_query_list_lock); 2040 spin_unlock(&tomoyo_query_list_lock);
2033 if (sscanf(data, "A%u=%u", &serial, &answer) != 2) 2041 if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2034 return -EINVAL; 2042 return -EINVAL;
2035 spin_lock(&tomoyo_query_list_lock); 2043 spin_lock(&tomoyo_query_list_lock);
2036 list_for_each(tmp, &tomoyo_query_list) { 2044 list_for_each(tmp, &tomoyo_query_list) {
2037 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list); 2045 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2038 if (ptr->serial != serial) 2046 if (ptr->serial != serial)
2039 continue; 2047 continue;
2040 if (!ptr->answer) 2048 if (!ptr->answer)
2041 ptr->answer = answer; 2049 ptr->answer = answer;
2042 break; 2050 break;
2043 } 2051 }
2044 spin_unlock(&tomoyo_query_list_lock); 2052 spin_unlock(&tomoyo_query_list_lock);
2045 return 0; 2053 return 0;
2046 } 2054 }
2047 2055
2048 /** 2056 /**
2049 * tomoyo_read_version: Get version. 2057 * tomoyo_read_version: Get version.
2050 * 2058 *
2051 * @head: Pointer to "struct tomoyo_io_buffer". 2059 * @head: Pointer to "struct tomoyo_io_buffer".
2052 * 2060 *
2053 * Returns version information. 2061 * Returns version information.
2054 */ 2062 */
2055 static void tomoyo_read_version(struct tomoyo_io_buffer *head) 2063 static void tomoyo_read_version(struct tomoyo_io_buffer *head)
2056 { 2064 {
2057 if (!head->r.eof) { 2065 if (!head->r.eof) {
2058 tomoyo_io_printf(head, "2.4.0"); 2066 tomoyo_io_printf(head, "2.4.0");
2059 head->r.eof = true; 2067 head->r.eof = true;
2060 } 2068 }
2061 } 2069 }
2062 2070
2063 /** 2071 /**
2064 * tomoyo_read_self_domain - Get the current process's domainname. 2072 * tomoyo_read_self_domain - Get the current process's domainname.
2065 * 2073 *
2066 * @head: Pointer to "struct tomoyo_io_buffer". 2074 * @head: Pointer to "struct tomoyo_io_buffer".
2067 * 2075 *
2068 * Returns the current process's domainname. 2076 * Returns the current process's domainname.
2069 */ 2077 */
2070 static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head) 2078 static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
2071 { 2079 {
2072 if (!head->r.eof) { 2080 if (!head->r.eof) {
2073 /* 2081 /*
2074 * tomoyo_domain()->domainname != NULL 2082 * tomoyo_domain()->domainname != NULL
2075 * because every process belongs to a domain and 2083 * because every process belongs to a domain and
2076 * the domain's name cannot be NULL. 2084 * the domain's name cannot be NULL.
2077 */ 2085 */
2078 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name); 2086 tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
2079 head->r.eof = true; 2087 head->r.eof = true;
2080 } 2088 }
2081 } 2089 }
2082 2090
2083 /* String table for /sys/kernel/security/tomoyo/stat interface. */ 2091 /* String table for /sys/kernel/security/tomoyo/stat interface. */
2084 static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = { 2092 static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
2085 [TOMOYO_STAT_POLICY_UPDATES] = "update:", 2093 [TOMOYO_STAT_POLICY_UPDATES] = "update:",
2086 [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:", 2094 [TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
2087 [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:", 2095 [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
2088 [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:", 2096 [TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
2089 }; 2097 };
2090 2098
2091 /* String table for /sys/kernel/security/tomoyo/stat interface. */ 2099 /* String table for /sys/kernel/security/tomoyo/stat interface. */
2092 static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = { 2100 static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
2093 [TOMOYO_MEMORY_POLICY] = "policy:", 2101 [TOMOYO_MEMORY_POLICY] = "policy:",
2094 [TOMOYO_MEMORY_AUDIT] = "audit log:", 2102 [TOMOYO_MEMORY_AUDIT] = "audit log:",
2095 [TOMOYO_MEMORY_QUERY] = "query message:", 2103 [TOMOYO_MEMORY_QUERY] = "query message:",
2096 }; 2104 };
2097 2105
2098 /* Timestamp counter for last updated. */ 2106 /* Timestamp counter for last updated. */
2099 static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT]; 2107 static unsigned int tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
2100 /* Counter for number of updates. */ 2108 /* Counter for number of updates. */
2101 static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT]; 2109 static unsigned int tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
2102 2110
2103 /** 2111 /**
2104 * tomoyo_update_stat - Update statistic counters. 2112 * tomoyo_update_stat - Update statistic counters.
2105 * 2113 *
2106 * @index: Index for policy type. 2114 * @index: Index for policy type.
2107 * 2115 *
2108 * Returns nothing. 2116 * Returns nothing.
2109 */ 2117 */
2110 void tomoyo_update_stat(const u8 index) 2118 void tomoyo_update_stat(const u8 index)
2111 { 2119 {
2112 struct timeval tv; 2120 struct timeval tv;
2113 do_gettimeofday(&tv); 2121 do_gettimeofday(&tv);
2114 /* 2122 /*
2115 * I don't use atomic operations because race condition is not fatal. 2123 * I don't use atomic operations because race condition is not fatal.
2116 */ 2124 */
2117 tomoyo_stat_updated[index]++; 2125 tomoyo_stat_updated[index]++;
2118 tomoyo_stat_modified[index] = tv.tv_sec; 2126 tomoyo_stat_modified[index] = tv.tv_sec;
2119 } 2127 }
2120 2128
2121 /** 2129 /**
2122 * tomoyo_read_stat - Read statistic data. 2130 * tomoyo_read_stat - Read statistic data.
2123 * 2131 *
2124 * @head: Pointer to "struct tomoyo_io_buffer". 2132 * @head: Pointer to "struct tomoyo_io_buffer".
2125 * 2133 *
2126 * Returns nothing. 2134 * Returns nothing.
2127 */ 2135 */
2128 static void tomoyo_read_stat(struct tomoyo_io_buffer *head) 2136 static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
2129 { 2137 {
2130 u8 i; 2138 u8 i;
2131 unsigned int total = 0; 2139 unsigned int total = 0;
2132 if (head->r.eof) 2140 if (head->r.eof)
2133 return; 2141 return;
2134 for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) { 2142 for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
2135 tomoyo_io_printf(head, "Policy %-30s %10u", 2143 tomoyo_io_printf(head, "Policy %-30s %10u",
2136 tomoyo_policy_headers[i], 2144 tomoyo_policy_headers[i],
2137 tomoyo_stat_updated[i]); 2145 tomoyo_stat_updated[i]);
2138 if (tomoyo_stat_modified[i]) { 2146 if (tomoyo_stat_modified[i]) {
2139 struct tomoyo_time stamp; 2147 struct tomoyo_time stamp;
2140 tomoyo_convert_time(tomoyo_stat_modified[i], &stamp); 2148 tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
2141 tomoyo_io_printf(head, " (Last: %04u/%02u/%02u " 2149 tomoyo_io_printf(head, " (Last: %04u/%02u/%02u "
2142 "%02u:%02u:%02u)", 2150 "%02u:%02u:%02u)",
2143 stamp.year, stamp.month, stamp.day, 2151 stamp.year, stamp.month, stamp.day,
2144 stamp.hour, stamp.min, stamp.sec); 2152 stamp.hour, stamp.min, stamp.sec);
2145 } 2153 }
2146 tomoyo_set_lf(head); 2154 tomoyo_set_lf(head);
2147 } 2155 }
2148 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) { 2156 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
2149 unsigned int used = tomoyo_memory_used[i]; 2157 unsigned int used = tomoyo_memory_used[i];
2150 total += used; 2158 total += used;
2151 tomoyo_io_printf(head, "Memory used by %-22s %10u", 2159 tomoyo_io_printf(head, "Memory used by %-22s %10u",
2152 tomoyo_memory_headers[i], used); 2160 tomoyo_memory_headers[i], used);
2153 used = tomoyo_memory_quota[i]; 2161 used = tomoyo_memory_quota[i];
2154 if (used) 2162 if (used)
2155 tomoyo_io_printf(head, " (Quota: %10u)", used); 2163 tomoyo_io_printf(head, " (Quota: %10u)", used);
2156 tomoyo_set_lf(head); 2164 tomoyo_set_lf(head);
2157 } 2165 }
2158 tomoyo_io_printf(head, "Total memory used: %10u\n", 2166 tomoyo_io_printf(head, "Total memory used: %10u\n",
2159 total); 2167 total);
2160 head->r.eof = true; 2168 head->r.eof = true;
2161 } 2169 }
2162 2170
2163 /** 2171 /**
2164 * tomoyo_write_stat - Set memory quota. 2172 * tomoyo_write_stat - Set memory quota.
2165 * 2173 *
2166 * @head: Pointer to "struct tomoyo_io_buffer". 2174 * @head: Pointer to "struct tomoyo_io_buffer".
2167 * 2175 *
2168 * Returns 0. 2176 * Returns 0.
2169 */ 2177 */
2170 static int tomoyo_write_stat(struct tomoyo_io_buffer *head) 2178 static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
2171 { 2179 {
2172 char *data = head->write_buf; 2180 char *data = head->write_buf;
2173 u8 i; 2181 u8 i;
2174 if (tomoyo_str_starts(&data, "Memory used by ")) 2182 if (tomoyo_str_starts(&data, "Memory used by "))
2175 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) 2183 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
2176 if (tomoyo_str_starts(&data, tomoyo_memory_headers[i])) 2184 if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
2177 sscanf(data, "%u", &tomoyo_memory_quota[i]); 2185 sscanf(data, "%u", &tomoyo_memory_quota[i]);
2178 return 0; 2186 return 0;
2179 } 2187 }
2180 2188
2181 /** 2189 /**
2182 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface. 2190 * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
2183 * 2191 *
2184 * @type: Type of interface. 2192 * @type: Type of interface.
2185 * @file: Pointer to "struct file". 2193 * @file: Pointer to "struct file".
2186 * 2194 *
2187 * Returns 0 on success, negative value otherwise. 2195 * Returns 0 on success, negative value otherwise.
2188 */ 2196 */
2189 int tomoyo_open_control(const u8 type, struct file *file) 2197 int tomoyo_open_control(const u8 type, struct file *file)
2190 { 2198 {
2191 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS); 2199 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
2192 2200
2193 if (!head) 2201 if (!head)
2194 return -ENOMEM; 2202 return -ENOMEM;
2195 mutex_init(&head->io_sem); 2203 mutex_init(&head->io_sem);
2196 head->type = type; 2204 head->type = type;
2197 switch (type) { 2205 switch (type) {
2198 case TOMOYO_DOMAINPOLICY: 2206 case TOMOYO_DOMAINPOLICY:
2199 /* /sys/kernel/security/tomoyo/domain_policy */ 2207 /* /sys/kernel/security/tomoyo/domain_policy */
2200 head->write = tomoyo_write_domain; 2208 head->write = tomoyo_write_domain;
2201 head->read = tomoyo_read_domain; 2209 head->read = tomoyo_read_domain;
2202 break; 2210 break;
2203 case TOMOYO_EXCEPTIONPOLICY: 2211 case TOMOYO_EXCEPTIONPOLICY:
2204 /* /sys/kernel/security/tomoyo/exception_policy */ 2212 /* /sys/kernel/security/tomoyo/exception_policy */
2205 head->write = tomoyo_write_exception; 2213 head->write = tomoyo_write_exception;
2206 head->read = tomoyo_read_exception; 2214 head->read = tomoyo_read_exception;
2207 break; 2215 break;
2208 case TOMOYO_AUDIT: 2216 case TOMOYO_AUDIT:
2209 /* /sys/kernel/security/tomoyo/audit */ 2217 /* /sys/kernel/security/tomoyo/audit */
2210 head->poll = tomoyo_poll_log; 2218 head->poll = tomoyo_poll_log;
2211 head->read = tomoyo_read_log; 2219 head->read = tomoyo_read_log;
2212 break; 2220 break;
2213 case TOMOYO_SELFDOMAIN: 2221 case TOMOYO_SELFDOMAIN:
2214 /* /sys/kernel/security/tomoyo/self_domain */ 2222 /* /sys/kernel/security/tomoyo/self_domain */
2215 head->read = tomoyo_read_self_domain; 2223 head->read = tomoyo_read_self_domain;
2216 break; 2224 break;
2217 case TOMOYO_PROCESS_STATUS: 2225 case TOMOYO_PROCESS_STATUS:
2218 /* /sys/kernel/security/tomoyo/.process_status */ 2226 /* /sys/kernel/security/tomoyo/.process_status */
2219 head->write = tomoyo_write_pid; 2227 head->write = tomoyo_write_pid;
2220 head->read = tomoyo_read_pid; 2228 head->read = tomoyo_read_pid;
2221 break; 2229 break;
2222 case TOMOYO_VERSION: 2230 case TOMOYO_VERSION:
2223 /* /sys/kernel/security/tomoyo/version */ 2231 /* /sys/kernel/security/tomoyo/version */
2224 head->read = tomoyo_read_version; 2232 head->read = tomoyo_read_version;
2225 head->readbuf_size = 128; 2233 head->readbuf_size = 128;
2226 break; 2234 break;
2227 case TOMOYO_STAT: 2235 case TOMOYO_STAT:
2228 /* /sys/kernel/security/tomoyo/stat */ 2236 /* /sys/kernel/security/tomoyo/stat */
2229 head->write = tomoyo_write_stat; 2237 head->write = tomoyo_write_stat;
2230 head->read = tomoyo_read_stat; 2238 head->read = tomoyo_read_stat;
2231 head->readbuf_size = 1024; 2239 head->readbuf_size = 1024;
2232 break; 2240 break;
2233 case TOMOYO_PROFILE: 2241 case TOMOYO_PROFILE:
2234 /* /sys/kernel/security/tomoyo/profile */ 2242 /* /sys/kernel/security/tomoyo/profile */
2235 head->write = tomoyo_write_profile; 2243 head->write = tomoyo_write_profile;
2236 head->read = tomoyo_read_profile; 2244 head->read = tomoyo_read_profile;
2237 break; 2245 break;
2238 case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */ 2246 case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
2239 head->poll = tomoyo_poll_query; 2247 head->poll = tomoyo_poll_query;
2240 head->write = tomoyo_write_answer; 2248 head->write = tomoyo_write_answer;
2241 head->read = tomoyo_read_query; 2249 head->read = tomoyo_read_query;
2242 break; 2250 break;
2243 case TOMOYO_MANAGER: 2251 case TOMOYO_MANAGER:
2244 /* /sys/kernel/security/tomoyo/manager */ 2252 /* /sys/kernel/security/tomoyo/manager */
2245 head->write = tomoyo_write_manager; 2253 head->write = tomoyo_write_manager;
2246 head->read = tomoyo_read_manager; 2254 head->read = tomoyo_read_manager;
2247 break; 2255 break;
2248 } 2256 }
2249 if (!(file->f_mode & FMODE_READ)) { 2257 if (!(file->f_mode & FMODE_READ)) {
2250 /* 2258 /*
2251 * No need to allocate read_buf since it is not opened 2259 * No need to allocate read_buf since it is not opened
2252 * for reading. 2260 * for reading.
2253 */ 2261 */
2254 head->read = NULL; 2262 head->read = NULL;
2255 head->poll = NULL; 2263 head->poll = NULL;
2256 } else if (!head->poll) { 2264 } else if (!head->poll) {
2257 /* Don't allocate read_buf for poll() access. */ 2265 /* Don't allocate read_buf for poll() access. */
2258 if (!head->readbuf_size) 2266 if (!head->readbuf_size)
2259 head->readbuf_size = 4096 * 2; 2267 head->readbuf_size = 4096 * 2;
2260 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS); 2268 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
2261 if (!head->read_buf) { 2269 if (!head->read_buf) {
2262 kfree(head); 2270 kfree(head);
2263 return -ENOMEM; 2271 return -ENOMEM;
2264 } 2272 }
2265 } 2273 }
2266 if (!(file->f_mode & FMODE_WRITE)) { 2274 if (!(file->f_mode & FMODE_WRITE)) {
2267 /* 2275 /*
2268 * No need to allocate write_buf since it is not opened 2276 * No need to allocate write_buf since it is not opened
2269 * for writing. 2277 * for writing.
2270 */ 2278 */
2271 head->write = NULL; 2279 head->write = NULL;
2272 } else if (head->write) { 2280 } else if (head->write) {
2273 head->writebuf_size = 4096 * 2; 2281 head->writebuf_size = 4096 * 2;
2274 head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS); 2282 head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
2275 if (!head->write_buf) { 2283 if (!head->write_buf) {
2276 kfree(head->read_buf); 2284 kfree(head->read_buf);
2277 kfree(head); 2285 kfree(head);
2278 return -ENOMEM; 2286 return -ENOMEM;
2279 } 2287 }
2280 } 2288 }
2281 /* 2289 /*
2282 * If the file is /sys/kernel/security/tomoyo/query , increment the 2290 * If the file is /sys/kernel/security/tomoyo/query , increment the
2283 * observer counter. 2291 * observer counter.
2284 * The obserber counter is used by tomoyo_supervisor() to see if 2292 * The obserber counter is used by tomoyo_supervisor() to see if
2285 * there is some process monitoring /sys/kernel/security/tomoyo/query. 2293 * there is some process monitoring /sys/kernel/security/tomoyo/query.
2286 */ 2294 */
2287 if (type == TOMOYO_QUERY) 2295 if (type == TOMOYO_QUERY)
2288 atomic_inc(&tomoyo_query_observers); 2296 atomic_inc(&tomoyo_query_observers);
2289 file->private_data = head; 2297 file->private_data = head;
2290 tomoyo_notify_gc(head, true); 2298 tomoyo_notify_gc(head, true);
2291 return 0; 2299 return 0;
2292 } 2300 }
2293 2301
2294 /** 2302 /**
2295 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface. 2303 * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2296 * 2304 *
2297 * @file: Pointer to "struct file". 2305 * @file: Pointer to "struct file".
2298 * @wait: Pointer to "poll_table". 2306 * @wait: Pointer to "poll_table".
2299 * 2307 *
2300 * Waits for read readiness. 2308 * Waits for read readiness.
2301 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and 2309 * /sys/kernel/security/tomoyo/query is handled by /usr/sbin/tomoyo-queryd and
2302 * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd. 2310 * /sys/kernel/security/tomoyo/audit is handled by /usr/sbin/tomoyo-auditd.
2303 */ 2311 */
2304 int tomoyo_poll_control(struct file *file, poll_table *wait) 2312 int tomoyo_poll_control(struct file *file, poll_table *wait)
2305 { 2313 {
2306 struct tomoyo_io_buffer *head = file->private_data; 2314 struct tomoyo_io_buffer *head = file->private_data;
2307 if (!head->poll) 2315 if (!head->poll)
2308 return -ENOSYS; 2316 return -ENOSYS;
2309 return head->poll(file, wait); 2317 return head->poll(file, wait);
2310 } 2318 }
2311 2319
2312 /** 2320 /**
2313 * tomoyo_set_namespace_cursor - Set namespace to read. 2321 * tomoyo_set_namespace_cursor - Set namespace to read.
2314 * 2322 *
2315 * @head: Pointer to "struct tomoyo_io_buffer". 2323 * @head: Pointer to "struct tomoyo_io_buffer".
2316 * 2324 *
2317 * Returns nothing. 2325 * Returns nothing.
2318 */ 2326 */
2319 static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head) 2327 static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
2320 { 2328 {
2321 struct list_head *ns; 2329 struct list_head *ns;
2322 if (head->type != TOMOYO_EXCEPTIONPOLICY && 2330 if (head->type != TOMOYO_EXCEPTIONPOLICY &&
2323 head->type != TOMOYO_PROFILE) 2331 head->type != TOMOYO_PROFILE)
2324 return; 2332 return;
2325 /* 2333 /*
2326 * If this is the first read, or reading previous namespace finished 2334 * If this is the first read, or reading previous namespace finished
2327 * and has more namespaces to read, update the namespace cursor. 2335 * and has more namespaces to read, update the namespace cursor.
2328 */ 2336 */
2329 ns = head->r.ns; 2337 ns = head->r.ns;
2330 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) { 2338 if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
2331 /* Clearing is OK because tomoyo_flush() returned true. */ 2339 /* Clearing is OK because tomoyo_flush() returned true. */
2332 memset(&head->r, 0, sizeof(head->r)); 2340 memset(&head->r, 0, sizeof(head->r));
2333 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next; 2341 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
2334 } 2342 }
2335 } 2343 }
2336 2344
2337 /** 2345 /**
2338 * tomoyo_has_more_namespace - Check for unread namespaces. 2346 * tomoyo_has_more_namespace - Check for unread namespaces.
2339 * 2347 *
2340 * @head: Pointer to "struct tomoyo_io_buffer". 2348 * @head: Pointer to "struct tomoyo_io_buffer".
2341 * 2349 *
2342 * Returns true if we have more entries to print, false otherwise. 2350 * Returns true if we have more entries to print, false otherwise.
2343 */ 2351 */
2344 static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head) 2352 static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2345 { 2353 {
2346 return (head->type == TOMOYO_EXCEPTIONPOLICY || 2354 return (head->type == TOMOYO_EXCEPTIONPOLICY ||
2347 head->type == TOMOYO_PROFILE) && head->r.eof && 2355 head->type == TOMOYO_PROFILE) && head->r.eof &&
2348 head->r.ns->next != &tomoyo_namespace_list; 2356 head->r.ns->next != &tomoyo_namespace_list;
2349 } 2357 }
2350 2358
2351 /** 2359 /**
2352 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface. 2360 * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
2353 * 2361 *
2354 * @head: Pointer to "struct tomoyo_io_buffer". 2362 * @head: Pointer to "struct tomoyo_io_buffer".
2355 * @buffer: Poiner to buffer to write to. 2363 * @buffer: Poiner to buffer to write to.
2356 * @buffer_len: Size of @buffer. 2364 * @buffer_len: Size of @buffer.
2357 * 2365 *
2358 * Returns bytes read on success, negative value otherwise. 2366 * Returns bytes read on success, negative value otherwise.
2359 */ 2367 */
2360 ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer, 2368 ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2361 const int buffer_len) 2369 const int buffer_len)
2362 { 2370 {
2363 int len; 2371 int len;
2364 int idx; 2372 int idx;
2365 2373
2366 if (!head->read) 2374 if (!head->read)
2367 return -ENOSYS; 2375 return -ENOSYS;
2368 if (mutex_lock_interruptible(&head->io_sem)) 2376 if (mutex_lock_interruptible(&head->io_sem))
2369 return -EINTR; 2377 return -EINTR;
2370 head->read_user_buf = buffer; 2378 head->read_user_buf = buffer;
2371 head->read_user_buf_avail = buffer_len; 2379 head->read_user_buf_avail = buffer_len;
2372 idx = tomoyo_read_lock(); 2380 idx = tomoyo_read_lock();
2373 if (tomoyo_flush(head)) 2381 if (tomoyo_flush(head))
2374 /* Call the policy handler. */ 2382 /* Call the policy handler. */
2375 do { 2383 do {
2376 tomoyo_set_namespace_cursor(head); 2384 tomoyo_set_namespace_cursor(head);
2377 head->read(head); 2385 head->read(head);
2378 } while (tomoyo_flush(head) && 2386 } while (tomoyo_flush(head) &&
2379 tomoyo_has_more_namespace(head)); 2387 tomoyo_has_more_namespace(head));
2380 tomoyo_read_unlock(idx); 2388 tomoyo_read_unlock(idx);
2381 len = head->read_user_buf - buffer; 2389 len = head->read_user_buf - buffer;
2382 mutex_unlock(&head->io_sem); 2390 mutex_unlock(&head->io_sem);
2383 return len; 2391 return len;
2384 } 2392 }
2385 2393
2386 /** 2394 /**
2387 * tomoyo_parse_policy - Parse a policy line. 2395 * tomoyo_parse_policy - Parse a policy line.
2388 * 2396 *
2389 * @head: Poiter to "struct tomoyo_io_buffer". 2397 * @head: Poiter to "struct tomoyo_io_buffer".
2390 * @line: Line to parse. 2398 * @line: Line to parse.
2391 * 2399 *
2392 * Returns 0 on success, negative value otherwise. 2400 * Returns 0 on success, negative value otherwise.
2393 * 2401 *
2394 * Caller holds tomoyo_read_lock(). 2402 * Caller holds tomoyo_read_lock().
2395 */ 2403 */
2396 static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line) 2404 static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2397 { 2405 {
2398 /* Delete request? */ 2406 /* Delete request? */
2399 head->w.is_delete = !strncmp(line, "delete ", 7); 2407 head->w.is_delete = !strncmp(line, "delete ", 7);
2400 if (head->w.is_delete) 2408 if (head->w.is_delete)
2401 memmove(line, line + 7, strlen(line + 7) + 1); 2409 memmove(line, line + 7, strlen(line + 7) + 1);
2402 /* Selecting namespace to update. */ 2410 /* Selecting namespace to update. */
2403 if (head->type == TOMOYO_EXCEPTIONPOLICY || 2411 if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2404 head->type == TOMOYO_PROFILE) { 2412 head->type == TOMOYO_PROFILE) {
2405 if (*line == '<') { 2413 if (*line == '<') {
2406 char *cp = strchr(line, ' '); 2414 char *cp = strchr(line, ' ');
2407 if (cp) { 2415 if (cp) {
2408 *cp++ = '\0'; 2416 *cp++ = '\0';
2409 head->w.ns = tomoyo_assign_namespace(line); 2417 head->w.ns = tomoyo_assign_namespace(line);
2410 memmove(line, cp, strlen(cp) + 1); 2418 memmove(line, cp, strlen(cp) + 1);
2411 } else 2419 } else
2412 head->w.ns = NULL; 2420 head->w.ns = NULL;
2413 } else 2421 } else
2414 head->w.ns = &tomoyo_kernel_namespace; 2422 head->w.ns = &tomoyo_kernel_namespace;
2415 /* Don't allow updating if namespace is invalid. */ 2423 /* Don't allow updating if namespace is invalid. */
2416 if (!head->w.ns) 2424 if (!head->w.ns)
2417 return -ENOENT; 2425 return -ENOENT;
2418 } 2426 }
2419 /* Do the update. */ 2427 /* Do the update. */
2420 return head->write(head); 2428 return head->write(head);
2421 } 2429 }
2422 2430
2423 /** 2431 /**
2424 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface. 2432 * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
2425 * 2433 *
2426 * @head: Pointer to "struct tomoyo_io_buffer". 2434 * @head: Pointer to "struct tomoyo_io_buffer".
2427 * @buffer: Pointer to buffer to read from. 2435 * @buffer: Pointer to buffer to read from.
2428 * @buffer_len: Size of @buffer. 2436 * @buffer_len: Size of @buffer.
2429 * 2437 *
2430 * Returns @buffer_len on success, negative value otherwise. 2438 * Returns @buffer_len on success, negative value otherwise.
2431 */ 2439 */
2432 ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head, 2440 ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
2433 const char __user *buffer, const int buffer_len) 2441 const char __user *buffer, const int buffer_len)
2434 { 2442 {
2435 int error = buffer_len; 2443 int error = buffer_len;
2436 size_t avail_len = buffer_len; 2444 size_t avail_len = buffer_len;
2437 char *cp0 = head->write_buf; 2445 char *cp0 = head->write_buf;
2438 int idx; 2446 int idx;
2439 if (!head->write) 2447 if (!head->write)
2440 return -ENOSYS; 2448 return -ENOSYS;
2441 if (!access_ok(VERIFY_READ, buffer, buffer_len)) 2449 if (!access_ok(VERIFY_READ, buffer, buffer_len))
2442 return -EFAULT; 2450 return -EFAULT;
2443 if (mutex_lock_interruptible(&head->io_sem)) 2451 if (mutex_lock_interruptible(&head->io_sem))
2444 return -EINTR; 2452 return -EINTR;
2445 idx = tomoyo_read_lock(); 2453 idx = tomoyo_read_lock();
2446 /* Read a line and dispatch it to the policy handler. */ 2454 /* Read a line and dispatch it to the policy handler. */
2447 while (avail_len > 0) { 2455 while (avail_len > 0) {
2448 char c; 2456 char c;
2449 if (head->w.avail >= head->writebuf_size - 1) { 2457 if (head->w.avail >= head->writebuf_size - 1) {
2450 const int len = head->writebuf_size * 2; 2458 const int len = head->writebuf_size * 2;
2451 char *cp = kzalloc(len, GFP_NOFS); 2459 char *cp = kzalloc(len, GFP_NOFS);
2452 if (!cp) { 2460 if (!cp) {
2453 error = -ENOMEM; 2461 error = -ENOMEM;
2454 break; 2462 break;
2455 } 2463 }
2456 memmove(cp, cp0, head->w.avail); 2464 memmove(cp, cp0, head->w.avail);
2457 kfree(cp0); 2465 kfree(cp0);
2458 head->write_buf = cp; 2466 head->write_buf = cp;
2459 cp0 = cp; 2467 cp0 = cp;
2460 head->writebuf_size = len; 2468 head->writebuf_size = len;
2461 } 2469 }
2462 if (get_user(c, buffer)) { 2470 if (get_user(c, buffer)) {
2463 error = -EFAULT; 2471 error = -EFAULT;
2464 break; 2472 break;
2465 } 2473 }
2466 buffer++; 2474 buffer++;
2467 avail_len--; 2475 avail_len--;
2468 cp0[head->w.avail++] = c; 2476 cp0[head->w.avail++] = c;
2469 if (c != '\n') 2477 if (c != '\n')
2470 continue; 2478 continue;
2471 cp0[head->w.avail - 1] = '\0'; 2479 cp0[head->w.avail - 1] = '\0';
2472 head->w.avail = 0; 2480 head->w.avail = 0;
2473 tomoyo_normalize_line(cp0); 2481 tomoyo_normalize_line(cp0);
2474 if (!strcmp(cp0, "reset")) { 2482 if (!strcmp(cp0, "reset")) {
2475 head->w.ns = &tomoyo_kernel_namespace; 2483 head->w.ns = &tomoyo_kernel_namespace;
2476 head->w.domain = NULL; 2484 head->w.domain = NULL;
2477 memset(&head->r, 0, sizeof(head->r)); 2485 memset(&head->r, 0, sizeof(head->r));
2478 continue; 2486 continue;
2479 } 2487 }
2480 /* Don't allow updating policies by non manager programs. */ 2488 /* Don't allow updating policies by non manager programs. */
2481 switch (head->type) { 2489 switch (head->type) {
2482 case TOMOYO_PROCESS_STATUS: 2490 case TOMOYO_PROCESS_STATUS:
2483 /* This does not write anything. */ 2491 /* This does not write anything. */
2484 break; 2492 break;
2485 case TOMOYO_DOMAINPOLICY: 2493 case TOMOYO_DOMAINPOLICY:
2486 if (tomoyo_select_domain(head, cp0)) 2494 if (tomoyo_select_domain(head, cp0))
2487 continue; 2495 continue;
2488 /* fall through */ 2496 /* fall through */
2489 case TOMOYO_EXCEPTIONPOLICY: 2497 case TOMOYO_EXCEPTIONPOLICY:
2490 if (!strcmp(cp0, "select transition_only")) { 2498 if (!strcmp(cp0, "select transition_only")) {
2491 head->r.print_transition_related_only = true; 2499 head->r.print_transition_related_only = true;
2492 continue; 2500 continue;
2493 } 2501 }
2494 /* fall through */ 2502 /* fall through */
2495 default: 2503 default:
2496 if (!tomoyo_manager()) { 2504 if (!tomoyo_manager()) {
2497 error = -EPERM; 2505 error = -EPERM;
2498 goto out; 2506 goto out;
2499 } 2507 }
2500 } 2508 }
2501 switch (tomoyo_parse_policy(head, cp0)) { 2509 switch (tomoyo_parse_policy(head, cp0)) {
2502 case -EPERM: 2510 case -EPERM:
2503 error = -EPERM; 2511 error = -EPERM;
2504 goto out; 2512 goto out;
2505 case 0: 2513 case 0:
2506 switch (head->type) { 2514 switch (head->type) {
2507 case TOMOYO_DOMAINPOLICY: 2515 case TOMOYO_DOMAINPOLICY:
2508 case TOMOYO_EXCEPTIONPOLICY: 2516 case TOMOYO_EXCEPTIONPOLICY:
2509 case TOMOYO_STAT: 2517 case TOMOYO_STAT:
2510 case TOMOYO_PROFILE: 2518 case TOMOYO_PROFILE:
2511 case TOMOYO_MANAGER: 2519 case TOMOYO_MANAGER:
2512 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES); 2520 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2513 break; 2521 break;
2514 default: 2522 default:
2515 break; 2523 break;
2516 } 2524 }
2517 break; 2525 break;
2518 } 2526 }
2519 } 2527 }
2520 out: 2528 out:
2521 tomoyo_read_unlock(idx); 2529 tomoyo_read_unlock(idx);
2522 mutex_unlock(&head->io_sem); 2530 mutex_unlock(&head->io_sem);
2523 return error; 2531 return error;
2524 } 2532 }
2525 2533
2526 /** 2534 /**
2527 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface. 2535 * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2528 * 2536 *
2529 * @head: Pointer to "struct tomoyo_io_buffer". 2537 * @head: Pointer to "struct tomoyo_io_buffer".
2530 * 2538 *
2531 * Returns 0. 2539 * Returns 0.
2532 */ 2540 */
2533 int tomoyo_close_control(struct tomoyo_io_buffer *head) 2541 int tomoyo_close_control(struct tomoyo_io_buffer *head)
2534 { 2542 {
2535 /* 2543 /*
2536 * If the file is /sys/kernel/security/tomoyo/query , decrement the 2544 * If the file is /sys/kernel/security/tomoyo/query , decrement the
2537 * observer counter. 2545 * observer counter.
2538 */ 2546 */
2539 if (head->type == TOMOYO_QUERY && 2547 if (head->type == TOMOYO_QUERY &&
2540 atomic_dec_and_test(&tomoyo_query_observers)) 2548 atomic_dec_and_test(&tomoyo_query_observers))
2541 wake_up_all(&tomoyo_answer_wait); 2549 wake_up_all(&tomoyo_answer_wait);
2542 tomoyo_notify_gc(head, false); 2550 tomoyo_notify_gc(head, false);
2543 return 0; 2551 return 0;
2544 } 2552 }
2545 2553
2546 /** 2554 /**
2547 * tomoyo_check_profile - Check all profiles currently assigned to domains are defined. 2555 * tomoyo_check_profile - Check all profiles currently assigned to domains are defined.
2548 */ 2556 */
2549 void tomoyo_check_profile(void) 2557 void tomoyo_check_profile(void)
2550 { 2558 {
2551 struct tomoyo_domain_info *domain; 2559 struct tomoyo_domain_info *domain;
2552 const int idx = tomoyo_read_lock(); 2560 const int idx = tomoyo_read_lock();
2553 tomoyo_policy_loaded = true; 2561 tomoyo_policy_loaded = true;
2554 printk(KERN_INFO "TOMOYO: 2.4.0\n"); 2562 printk(KERN_INFO "TOMOYO: 2.4.0\n");
2555 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2563 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
2556 const u8 profile = domain->profile; 2564 const u8 profile = domain->profile;
2557 const struct tomoyo_policy_namespace *ns = domain->ns; 2565 const struct tomoyo_policy_namespace *ns = domain->ns;
2558 if (ns->profile_version != 20100903) 2566 if (ns->profile_version != 20100903)
2559 printk(KERN_ERR 2567 printk(KERN_ERR
2560 "Profile version %u is not supported.\n", 2568 "Profile version %u is not supported.\n",
2561 ns->profile_version); 2569 ns->profile_version);
2562 else if (!ns->profile_ptr[profile]) 2570 else if (!ns->profile_ptr[profile])
2563 printk(KERN_ERR 2571 printk(KERN_ERR
2564 "Profile %u (used by '%s') is not defined.\n", 2572 "Profile %u (used by '%s') is not defined.\n",
2565 profile, domain->domainname->name); 2573 profile, domain->domainname->name);
2566 else 2574 else
2567 continue; 2575 continue;
2568 printk(KERN_ERR 2576 printk(KERN_ERR
2569 "Userland tools for TOMOYO 2.4 must be installed and " 2577 "Userland tools for TOMOYO 2.4 must be installed and "
2570 "policy must be initialized.\n"); 2578 "policy must be initialized.\n");
2571 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ " 2579 printk(KERN_ERR "Please see http://tomoyo.sourceforge.jp/2.4/ "
2572 "for more information.\n"); 2580 "for more information.\n");
2573 panic("STOP!"); 2581 panic("STOP!");
2574 } 2582 }
2575 tomoyo_read_unlock(idx); 2583 tomoyo_read_unlock(idx);
2576 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2584 printk(KERN_INFO "Mandatory Access Control activated.\n");
2577 } 2585 }
2578 2586
2579 /** 2587 /**
2580 * tomoyo_load_builtin_policy - Load built-in policy. 2588 * tomoyo_load_builtin_policy - Load built-in policy.
2581 * 2589 *
2582 * Returns nothing. 2590 * Returns nothing.
2583 */ 2591 */
2584 void __init tomoyo_load_builtin_policy(void) 2592 void __init tomoyo_load_builtin_policy(void)
2585 { 2593 {
2586 /* 2594 /*
2587 * This include file is manually created and contains built-in policy 2595 * This include file is manually created and contains built-in policy
2588 * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy", 2596 * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
2589 * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager", 2597 * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
2590 * "tomoyo_builtin_stat" in the form of "static char [] __initdata". 2598 * "tomoyo_builtin_stat" in the form of "static char [] __initdata".
2591 */ 2599 */
2592 #include "builtin-policy.h" 2600 #include "builtin-policy.h"
2593 u8 i; 2601 u8 i;
2594 const int idx = tomoyo_read_lock(); 2602 const int idx = tomoyo_read_lock();
2595 for (i = 0; i < 5; i++) { 2603 for (i = 0; i < 5; i++) {
2596 struct tomoyo_io_buffer head = { }; 2604 struct tomoyo_io_buffer head = { };
2597 char *start = ""; 2605 char *start = "";
2598 switch (i) { 2606 switch (i) {
2599 case 0: 2607 case 0:
2600 start = tomoyo_builtin_profile; 2608 start = tomoyo_builtin_profile;
2601 head.type = TOMOYO_PROFILE; 2609 head.type = TOMOYO_PROFILE;
2602 head.write = tomoyo_write_profile; 2610 head.write = tomoyo_write_profile;
2603 break; 2611 break;
2604 case 1: 2612 case 1:
2605 start = tomoyo_builtin_exception_policy; 2613 start = tomoyo_builtin_exception_policy;
2606 head.type = TOMOYO_EXCEPTIONPOLICY; 2614 head.type = TOMOYO_EXCEPTIONPOLICY;
2607 head.write = tomoyo_write_exception; 2615 head.write = tomoyo_write_exception;
2608 break; 2616 break;
2609 case 2: 2617 case 2:
2610 start = tomoyo_builtin_domain_policy; 2618 start = tomoyo_builtin_domain_policy;
2611 head.type = TOMOYO_DOMAINPOLICY; 2619 head.type = TOMOYO_DOMAINPOLICY;
2612 head.write = tomoyo_write_domain; 2620 head.write = tomoyo_write_domain;
2613 break; 2621 break;
2614 case 3: 2622 case 3:
2615 start = tomoyo_builtin_manager; 2623 start = tomoyo_builtin_manager;
2616 head.type = TOMOYO_MANAGER; 2624 head.type = TOMOYO_MANAGER;
2617 head.write = tomoyo_write_manager; 2625 head.write = tomoyo_write_manager;
2618 break; 2626 break;
2619 case 4: 2627 case 4:
2620 start = tomoyo_builtin_stat; 2628 start = tomoyo_builtin_stat;
2621 head.type = TOMOYO_STAT; 2629 head.type = TOMOYO_STAT;
2622 head.write = tomoyo_write_stat; 2630 head.write = tomoyo_write_stat;
2623 break; 2631 break;
2624 } 2632 }
2625 while (1) { 2633 while (1) {
2626 char *end = strchr(start, '\n'); 2634 char *end = strchr(start, '\n');
2627 if (!end) 2635 if (!end)
2628 break; 2636 break;
2629 *end = '\0'; 2637 *end = '\0';
2630 tomoyo_normalize_line(start); 2638 tomoyo_normalize_line(start);
2631 head.write_buf = start; 2639 head.write_buf = start;
2632 tomoyo_parse_policy(&head, start); 2640 tomoyo_parse_policy(&head, start);
2633 start = end + 1; 2641 start = end + 1;
2634 } 2642 }
2635 } 2643 }
2636 tomoyo_read_unlock(idx); 2644 tomoyo_read_unlock(idx);
2637 #ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 2645 #ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
2638 tomoyo_check_profile(); 2646 tomoyo_check_profile();
2639 #endif 2647 #endif
security/tomoyo/domain.c
1 /* 1 /*
2 * security/tomoyo/domain.c 2 * security/tomoyo/domain.c
3 * 3 *
4 * Domain transition functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include "common.h" 7 #include "common.h"
10 #include <linux/binfmts.h> 8 #include <linux/binfmts.h>
11 #include <linux/slab.h> 9 #include <linux/slab.h>
12 10
13 /* Variables definitions.*/ 11 /* Variables definitions.*/
14 12
15 /* The initial domain. */ 13 /* The initial domain. */
16 struct tomoyo_domain_info tomoyo_kernel_domain; 14 struct tomoyo_domain_info tomoyo_kernel_domain;
17 15
18 /** 16 /**
19 * tomoyo_update_policy - Update an entry for exception policy. 17 * tomoyo_update_policy - Update an entry for exception policy.
20 * 18 *
21 * @new_entry: Pointer to "struct tomoyo_acl_info". 19 * @new_entry: Pointer to "struct tomoyo_acl_info".
22 * @size: Size of @new_entry in bytes. 20 * @size: Size of @new_entry in bytes.
23 * @param: Pointer to "struct tomoyo_acl_param". 21 * @param: Pointer to "struct tomoyo_acl_param".
24 * @check_duplicate: Callback function to find duplicated entry. 22 * @check_duplicate: Callback function to find duplicated entry.
25 * 23 *
26 * Returns 0 on success, negative value otherwise. 24 * Returns 0 on success, negative value otherwise.
27 * 25 *
28 * Caller holds tomoyo_read_lock(). 26 * Caller holds tomoyo_read_lock().
29 */ 27 */
30 int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, 28 int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
31 struct tomoyo_acl_param *param, 29 struct tomoyo_acl_param *param,
32 bool (*check_duplicate) (const struct tomoyo_acl_head 30 bool (*check_duplicate) (const struct tomoyo_acl_head
33 *, 31 *,
34 const struct tomoyo_acl_head 32 const struct tomoyo_acl_head
35 *)) 33 *))
36 { 34 {
37 int error = param->is_delete ? -ENOENT : -ENOMEM; 35 int error = param->is_delete ? -ENOENT : -ENOMEM;
38 struct tomoyo_acl_head *entry; 36 struct tomoyo_acl_head *entry;
39 struct list_head *list = param->list; 37 struct list_head *list = param->list;
40 38
41 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 39 if (mutex_lock_interruptible(&tomoyo_policy_lock))
42 return -ENOMEM; 40 return -ENOMEM;
43 list_for_each_entry_rcu(entry, list, list) { 41 list_for_each_entry_rcu(entry, list, list) {
44 if (!check_duplicate(entry, new_entry)) 42 if (!check_duplicate(entry, new_entry))
45 continue; 43 continue;
46 entry->is_deleted = param->is_delete; 44 entry->is_deleted = param->is_delete;
47 error = 0; 45 error = 0;
48 break; 46 break;
49 } 47 }
50 if (error && !param->is_delete) { 48 if (error && !param->is_delete) {
51 entry = tomoyo_commit_ok(new_entry, size); 49 entry = tomoyo_commit_ok(new_entry, size);
52 if (entry) { 50 if (entry) {
53 list_add_tail_rcu(&entry->list, list); 51 list_add_tail_rcu(&entry->list, list);
54 error = 0; 52 error = 0;
55 } 53 }
56 } 54 }
57 mutex_unlock(&tomoyo_policy_lock); 55 mutex_unlock(&tomoyo_policy_lock);
58 return error; 56 return error;
59 } 57 }
60 58
61 /** 59 /**
62 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry. 60 * tomoyo_same_acl_head - Check for duplicated "struct tomoyo_acl_info" entry.
63 * 61 *
64 * @a: Pointer to "struct tomoyo_acl_info". 62 * @a: Pointer to "struct tomoyo_acl_info".
65 * @b: Pointer to "struct tomoyo_acl_info". 63 * @b: Pointer to "struct tomoyo_acl_info".
66 * 64 *
67 * Returns true if @a == @b, false otherwise. 65 * Returns true if @a == @b, false otherwise.
68 */ 66 */
69 static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a, 67 static inline bool tomoyo_same_acl_head(const struct tomoyo_acl_info *a,
70 const struct tomoyo_acl_info *b) 68 const struct tomoyo_acl_info *b)
71 { 69 {
72 return a->type == b->type && a->cond == b->cond; 70 return a->type == b->type && a->cond == b->cond;
73 } 71 }
74 72
75 /** 73 /**
76 * tomoyo_update_domain - Update an entry for domain policy. 74 * tomoyo_update_domain - Update an entry for domain policy.
77 * 75 *
78 * @new_entry: Pointer to "struct tomoyo_acl_info". 76 * @new_entry: Pointer to "struct tomoyo_acl_info".
79 * @size: Size of @new_entry in bytes. 77 * @size: Size of @new_entry in bytes.
80 * @param: Pointer to "struct tomoyo_acl_param". 78 * @param: Pointer to "struct tomoyo_acl_param".
81 * @check_duplicate: Callback function to find duplicated entry. 79 * @check_duplicate: Callback function to find duplicated entry.
82 * @merge_duplicate: Callback function to merge duplicated entry. 80 * @merge_duplicate: Callback function to merge duplicated entry.
83 * 81 *
84 * Returns 0 on success, negative value otherwise. 82 * Returns 0 on success, negative value otherwise.
85 * 83 *
86 * Caller holds tomoyo_read_lock(). 84 * Caller holds tomoyo_read_lock().
87 */ 85 */
88 int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, 86 int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
89 struct tomoyo_acl_param *param, 87 struct tomoyo_acl_param *param,
90 bool (*check_duplicate) (const struct tomoyo_acl_info 88 bool (*check_duplicate) (const struct tomoyo_acl_info
91 *, 89 *,
92 const struct tomoyo_acl_info 90 const struct tomoyo_acl_info
93 *), 91 *),
94 bool (*merge_duplicate) (struct tomoyo_acl_info *, 92 bool (*merge_duplicate) (struct tomoyo_acl_info *,
95 struct tomoyo_acl_info *, 93 struct tomoyo_acl_info *,
96 const bool)) 94 const bool))
97 { 95 {
98 const bool is_delete = param->is_delete; 96 const bool is_delete = param->is_delete;
99 int error = is_delete ? -ENOENT : -ENOMEM; 97 int error = is_delete ? -ENOENT : -ENOMEM;
100 struct tomoyo_acl_info *entry; 98 struct tomoyo_acl_info *entry;
101 struct list_head * const list = param->list; 99 struct list_head * const list = param->list;
102 100
103 if (param->data[0]) { 101 if (param->data[0]) {
104 new_entry->cond = tomoyo_get_condition(param); 102 new_entry->cond = tomoyo_get_condition(param);
105 if (!new_entry->cond) 103 if (!new_entry->cond)
106 return -EINVAL; 104 return -EINVAL;
107 } 105 }
108 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 106 if (mutex_lock_interruptible(&tomoyo_policy_lock))
109 goto out; 107 goto out;
110 list_for_each_entry_rcu(entry, list, list) { 108 list_for_each_entry_rcu(entry, list, list) {
111 if (!tomoyo_same_acl_head(entry, new_entry) || 109 if (!tomoyo_same_acl_head(entry, new_entry) ||
112 !check_duplicate(entry, new_entry)) 110 !check_duplicate(entry, new_entry))
113 continue; 111 continue;
114 if (merge_duplicate) 112 if (merge_duplicate)
115 entry->is_deleted = merge_duplicate(entry, new_entry, 113 entry->is_deleted = merge_duplicate(entry, new_entry,
116 is_delete); 114 is_delete);
117 else 115 else
118 entry->is_deleted = is_delete; 116 entry->is_deleted = is_delete;
119 error = 0; 117 error = 0;
120 break; 118 break;
121 } 119 }
122 if (error && !is_delete) { 120 if (error && !is_delete) {
123 entry = tomoyo_commit_ok(new_entry, size); 121 entry = tomoyo_commit_ok(new_entry, size);
124 if (entry) { 122 if (entry) {
125 list_add_tail_rcu(&entry->list, list); 123 list_add_tail_rcu(&entry->list, list);
126 error = 0; 124 error = 0;
127 } 125 }
128 } 126 }
129 mutex_unlock(&tomoyo_policy_lock); 127 mutex_unlock(&tomoyo_policy_lock);
130 out: 128 out:
131 tomoyo_put_condition(new_entry->cond); 129 tomoyo_put_condition(new_entry->cond);
132 return error; 130 return error;
133 } 131 }
134 132
135 /** 133 /**
136 * tomoyo_check_acl - Do permission check. 134 * tomoyo_check_acl - Do permission check.
137 * 135 *
138 * @r: Pointer to "struct tomoyo_request_info". 136 * @r: Pointer to "struct tomoyo_request_info".
139 * @check_entry: Callback function to check type specific parameters. 137 * @check_entry: Callback function to check type specific parameters.
140 * 138 *
141 * Returns 0 on success, negative value otherwise. 139 * Returns 0 on success, negative value otherwise.
142 * 140 *
143 * Caller holds tomoyo_read_lock(). 141 * Caller holds tomoyo_read_lock().
144 */ 142 */
145 void tomoyo_check_acl(struct tomoyo_request_info *r, 143 void tomoyo_check_acl(struct tomoyo_request_info *r,
146 bool (*check_entry) (struct tomoyo_request_info *, 144 bool (*check_entry) (struct tomoyo_request_info *,
147 const struct tomoyo_acl_info *)) 145 const struct tomoyo_acl_info *))
148 { 146 {
149 const struct tomoyo_domain_info *domain = r->domain; 147 const struct tomoyo_domain_info *domain = r->domain;
150 struct tomoyo_acl_info *ptr; 148 struct tomoyo_acl_info *ptr;
151 bool retried = false; 149 bool retried = false;
152 const struct list_head *list = &domain->acl_info_list; 150 const struct list_head *list = &domain->acl_info_list;
153 151
154 retry: 152 retry:
155 list_for_each_entry_rcu(ptr, list, list) { 153 list_for_each_entry_rcu(ptr, list, list) {
156 if (ptr->is_deleted || ptr->type != r->param_type) 154 if (ptr->is_deleted || ptr->type != r->param_type)
157 continue; 155 continue;
158 if (!check_entry(r, ptr)) 156 if (!check_entry(r, ptr))
159 continue; 157 continue;
160 if (!tomoyo_condition(r, ptr->cond)) 158 if (!tomoyo_condition(r, ptr->cond))
161 continue; 159 continue;
162 r->granted = true; 160 r->granted = true;
163 return; 161 return;
164 } 162 }
165 if (!retried) { 163 if (!retried) {
166 retried = true; 164 retried = true;
167 list = &domain->ns->acl_group[domain->group]; 165 list = &domain->ns->acl_group[domain->group];
168 goto retry; 166 goto retry;
169 } 167 }
170 r->granted = false; 168 r->granted = false;
171 } 169 }
172 170
173 /* The list for "struct tomoyo_domain_info". */ 171 /* The list for "struct tomoyo_domain_info". */
174 LIST_HEAD(tomoyo_domain_list); 172 LIST_HEAD(tomoyo_domain_list);
175 173
176 /** 174 /**
177 * tomoyo_last_word - Get last component of a domainname. 175 * tomoyo_last_word - Get last component of a domainname.
178 * 176 *
179 * @name: Domainname to check. 177 * @name: Domainname to check.
180 * 178 *
181 * Returns the last word of @domainname. 179 * Returns the last word of @domainname.
182 */ 180 */
183 static const char *tomoyo_last_word(const char *name) 181 static const char *tomoyo_last_word(const char *name)
184 { 182 {
185 const char *cp = strrchr(name, ' '); 183 const char *cp = strrchr(name, ' ');
186 if (cp) 184 if (cp)
187 return cp + 1; 185 return cp + 1;
188 return name; 186 return name;
189 } 187 }
190 188
191 /** 189 /**
192 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry. 190 * tomoyo_same_transition_control - Check for duplicated "struct tomoyo_transition_control" entry.
193 * 191 *
194 * @a: Pointer to "struct tomoyo_acl_head". 192 * @a: Pointer to "struct tomoyo_acl_head".
195 * @b: Pointer to "struct tomoyo_acl_head". 193 * @b: Pointer to "struct tomoyo_acl_head".
196 * 194 *
197 * Returns true if @a == @b, false otherwise. 195 * Returns true if @a == @b, false otherwise.
198 */ 196 */
199 static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a, 197 static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a,
200 const struct tomoyo_acl_head *b) 198 const struct tomoyo_acl_head *b)
201 { 199 {
202 const struct tomoyo_transition_control *p1 = container_of(a, 200 const struct tomoyo_transition_control *p1 = container_of(a,
203 typeof(*p1), 201 typeof(*p1),
204 head); 202 head);
205 const struct tomoyo_transition_control *p2 = container_of(b, 203 const struct tomoyo_transition_control *p2 = container_of(b,
206 typeof(*p2), 204 typeof(*p2),
207 head); 205 head);
208 return p1->type == p2->type && p1->is_last_name == p2->is_last_name 206 return p1->type == p2->type && p1->is_last_name == p2->is_last_name
209 && p1->domainname == p2->domainname 207 && p1->domainname == p2->domainname
210 && p1->program == p2->program; 208 && p1->program == p2->program;
211 } 209 }
212 210
213 /** 211 /**
214 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list. 212 * tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list.
215 * 213 *
216 * @param: Pointer to "struct tomoyo_acl_param". 214 * @param: Pointer to "struct tomoyo_acl_param".
217 * @type: Type of this entry. 215 * @type: Type of this entry.
218 * 216 *
219 * Returns 0 on success, negative value otherwise. 217 * Returns 0 on success, negative value otherwise.
220 */ 218 */
221 int tomoyo_write_transition_control(struct tomoyo_acl_param *param, 219 int tomoyo_write_transition_control(struct tomoyo_acl_param *param,
222 const u8 type) 220 const u8 type)
223 { 221 {
224 struct tomoyo_transition_control e = { .type = type }; 222 struct tomoyo_transition_control e = { .type = type };
225 int error = param->is_delete ? -ENOENT : -ENOMEM; 223 int error = param->is_delete ? -ENOENT : -ENOMEM;
226 char *program = param->data; 224 char *program = param->data;
227 char *domainname = strstr(program, " from "); 225 char *domainname = strstr(program, " from ");
228 if (domainname) { 226 if (domainname) {
229 *domainname = '\0'; 227 *domainname = '\0';
230 domainname += 6; 228 domainname += 6;
231 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP || 229 } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP ||
232 type == TOMOYO_TRANSITION_CONTROL_KEEP) { 230 type == TOMOYO_TRANSITION_CONTROL_KEEP) {
233 domainname = program; 231 domainname = program;
234 program = NULL; 232 program = NULL;
235 } 233 }
236 if (program && strcmp(program, "any")) { 234 if (program && strcmp(program, "any")) {
237 if (!tomoyo_correct_path(program)) 235 if (!tomoyo_correct_path(program))
238 return -EINVAL; 236 return -EINVAL;
239 e.program = tomoyo_get_name(program); 237 e.program = tomoyo_get_name(program);
240 if (!e.program) 238 if (!e.program)
241 goto out; 239 goto out;
242 } 240 }
243 if (domainname && strcmp(domainname, "any")) { 241 if (domainname && strcmp(domainname, "any")) {
244 if (!tomoyo_correct_domain(domainname)) { 242 if (!tomoyo_correct_domain(domainname)) {
245 if (!tomoyo_correct_path(domainname)) 243 if (!tomoyo_correct_path(domainname))
246 goto out; 244 goto out;
247 e.is_last_name = true; 245 e.is_last_name = true;
248 } 246 }
249 e.domainname = tomoyo_get_name(domainname); 247 e.domainname = tomoyo_get_name(domainname);
250 if (!e.domainname) 248 if (!e.domainname)
251 goto out; 249 goto out;
252 } 250 }
253 param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL]; 251 param->list = &param->ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
254 error = tomoyo_update_policy(&e.head, sizeof(e), param, 252 error = tomoyo_update_policy(&e.head, sizeof(e), param,
255 tomoyo_same_transition_control); 253 tomoyo_same_transition_control);
256 out: 254 out:
257 tomoyo_put_name(e.domainname); 255 tomoyo_put_name(e.domainname);
258 tomoyo_put_name(e.program); 256 tomoyo_put_name(e.program);
259 return error; 257 return error;
260 } 258 }
261 259
262 /** 260 /**
263 * tomoyo_scan_transition - Try to find specific domain transition type. 261 * tomoyo_scan_transition - Try to find specific domain transition type.
264 * 262 *
265 * @list: Pointer to "struct list_head". 263 * @list: Pointer to "struct list_head".
266 * @domainname: The name of current domain. 264 * @domainname: The name of current domain.
267 * @program: The name of requested program. 265 * @program: The name of requested program.
268 * @last_name: The last component of @domainname. 266 * @last_name: The last component of @domainname.
269 * @type: One of values in "enum tomoyo_transition_type". 267 * @type: One of values in "enum tomoyo_transition_type".
270 * 268 *
271 * Returns true if found one, false otherwise. 269 * Returns true if found one, false otherwise.
272 * 270 *
273 * Caller holds tomoyo_read_lock(). 271 * Caller holds tomoyo_read_lock().
274 */ 272 */
275 static inline bool tomoyo_scan_transition 273 static inline bool tomoyo_scan_transition
276 (const struct list_head *list, const struct tomoyo_path_info *domainname, 274 (const struct list_head *list, const struct tomoyo_path_info *domainname,
277 const struct tomoyo_path_info *program, const char *last_name, 275 const struct tomoyo_path_info *program, const char *last_name,
278 const enum tomoyo_transition_type type) 276 const enum tomoyo_transition_type type)
279 { 277 {
280 const struct tomoyo_transition_control *ptr; 278 const struct tomoyo_transition_control *ptr;
281 list_for_each_entry_rcu(ptr, list, head.list) { 279 list_for_each_entry_rcu(ptr, list, head.list) {
282 if (ptr->head.is_deleted || ptr->type != type) 280 if (ptr->head.is_deleted || ptr->type != type)
283 continue; 281 continue;
284 if (ptr->domainname) { 282 if (ptr->domainname) {
285 if (!ptr->is_last_name) { 283 if (!ptr->is_last_name) {
286 if (ptr->domainname != domainname) 284 if (ptr->domainname != domainname)
287 continue; 285 continue;
288 } else { 286 } else {
289 /* 287 /*
290 * Use direct strcmp() since this is 288 * Use direct strcmp() since this is
291 * unlikely used. 289 * unlikely used.
292 */ 290 */
293 if (strcmp(ptr->domainname->name, last_name)) 291 if (strcmp(ptr->domainname->name, last_name))
294 continue; 292 continue;
295 } 293 }
296 } 294 }
297 if (ptr->program && tomoyo_pathcmp(ptr->program, program)) 295 if (ptr->program && tomoyo_pathcmp(ptr->program, program))
298 continue; 296 continue;
299 return true; 297 return true;
300 } 298 }
301 return false; 299 return false;
302 } 300 }
303 301
304 /** 302 /**
305 * tomoyo_transition_type - Get domain transition type. 303 * tomoyo_transition_type - Get domain transition type.
306 * 304 *
307 * @ns: Pointer to "struct tomoyo_policy_namespace". 305 * @ns: Pointer to "struct tomoyo_policy_namespace".
308 * @domainname: The name of current domain. 306 * @domainname: The name of current domain.
309 * @program: The name of requested program. 307 * @program: The name of requested program.
310 * 308 *
311 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes 309 * Returns TOMOYO_TRANSITION_CONTROL_TRANSIT if executing @program causes
312 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if 310 * domain transition across namespaces, TOMOYO_TRANSITION_CONTROL_INITIALIZE if
313 * executing @program reinitializes domain transition within that namespace, 311 * executing @program reinitializes domain transition within that namespace,
314 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname , 312 * TOMOYO_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
315 * others otherwise. 313 * others otherwise.
316 * 314 *
317 * Caller holds tomoyo_read_lock(). 315 * Caller holds tomoyo_read_lock().
318 */ 316 */
319 static enum tomoyo_transition_type tomoyo_transition_type 317 static enum tomoyo_transition_type tomoyo_transition_type
320 (const struct tomoyo_policy_namespace *ns, 318 (const struct tomoyo_policy_namespace *ns,
321 const struct tomoyo_path_info *domainname, 319 const struct tomoyo_path_info *domainname,
322 const struct tomoyo_path_info *program) 320 const struct tomoyo_path_info *program)
323 { 321 {
324 const char *last_name = tomoyo_last_word(domainname->name); 322 const char *last_name = tomoyo_last_word(domainname->name);
325 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET; 323 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
326 while (type < TOMOYO_MAX_TRANSITION_TYPE) { 324 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
327 const struct list_head * const list = 325 const struct list_head * const list =
328 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL]; 326 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
329 if (!tomoyo_scan_transition(list, domainname, program, 327 if (!tomoyo_scan_transition(list, domainname, program,
330 last_name, type)) { 328 last_name, type)) {
331 type++; 329 type++;
332 continue; 330 continue;
333 } 331 }
334 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET && 332 if (type != TOMOYO_TRANSITION_CONTROL_NO_RESET &&
335 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) 333 type != TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE)
336 break; 334 break;
337 /* 335 /*
338 * Do not check for reset_domain if no_reset_domain matched. 336 * Do not check for reset_domain if no_reset_domain matched.
339 * Do not check for initialize_domain if no_initialize_domain 337 * Do not check for initialize_domain if no_initialize_domain
340 * matched. 338 * matched.
341 */ 339 */
342 type++; 340 type++;
343 type++; 341 type++;
344 } 342 }
345 return type; 343 return type;
346 } 344 }
347 345
348 /** 346 /**
349 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry. 347 * tomoyo_same_aggregator - Check for duplicated "struct tomoyo_aggregator" entry.
350 * 348 *
351 * @a: Pointer to "struct tomoyo_acl_head". 349 * @a: Pointer to "struct tomoyo_acl_head".
352 * @b: Pointer to "struct tomoyo_acl_head". 350 * @b: Pointer to "struct tomoyo_acl_head".
353 * 351 *
354 * Returns true if @a == @b, false otherwise. 352 * Returns true if @a == @b, false otherwise.
355 */ 353 */
356 static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a, 354 static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a,
357 const struct tomoyo_acl_head *b) 355 const struct tomoyo_acl_head *b)
358 { 356 {
359 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), 357 const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1),
360 head); 358 head);
361 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), 359 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
362 head); 360 head);
363 return p1->original_name == p2->original_name && 361 return p1->original_name == p2->original_name &&
364 p1->aggregated_name == p2->aggregated_name; 362 p1->aggregated_name == p2->aggregated_name;
365 } 363 }
366 364
367 /** 365 /**
368 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list. 366 * tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list.
369 * 367 *
370 * @param: Pointer to "struct tomoyo_acl_param". 368 * @param: Pointer to "struct tomoyo_acl_param".
371 * 369 *
372 * Returns 0 on success, negative value otherwise. 370 * Returns 0 on success, negative value otherwise.
373 * 371 *
374 * Caller holds tomoyo_read_lock(). 372 * Caller holds tomoyo_read_lock().
375 */ 373 */
376 int tomoyo_write_aggregator(struct tomoyo_acl_param *param) 374 int tomoyo_write_aggregator(struct tomoyo_acl_param *param)
377 { 375 {
378 struct tomoyo_aggregator e = { }; 376 struct tomoyo_aggregator e = { };
379 int error = param->is_delete ? -ENOENT : -ENOMEM; 377 int error = param->is_delete ? -ENOENT : -ENOMEM;
380 const char *original_name = tomoyo_read_token(param); 378 const char *original_name = tomoyo_read_token(param);
381 const char *aggregated_name = tomoyo_read_token(param); 379 const char *aggregated_name = tomoyo_read_token(param);
382 if (!tomoyo_correct_word(original_name) || 380 if (!tomoyo_correct_word(original_name) ||
383 !tomoyo_correct_path(aggregated_name)) 381 !tomoyo_correct_path(aggregated_name))
384 return -EINVAL; 382 return -EINVAL;
385 e.original_name = tomoyo_get_name(original_name); 383 e.original_name = tomoyo_get_name(original_name);
386 e.aggregated_name = tomoyo_get_name(aggregated_name); 384 e.aggregated_name = tomoyo_get_name(aggregated_name);
387 if (!e.original_name || !e.aggregated_name || 385 if (!e.original_name || !e.aggregated_name ||
388 e.aggregated_name->is_patterned) /* No patterns allowed. */ 386 e.aggregated_name->is_patterned) /* No patterns allowed. */
389 goto out; 387 goto out;
390 param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 388 param->list = &param->ns->policy_list[TOMOYO_ID_AGGREGATOR];
391 error = tomoyo_update_policy(&e.head, sizeof(e), param, 389 error = tomoyo_update_policy(&e.head, sizeof(e), param,
392 tomoyo_same_aggregator); 390 tomoyo_same_aggregator);
393 out: 391 out:
394 tomoyo_put_name(e.original_name); 392 tomoyo_put_name(e.original_name);
395 tomoyo_put_name(e.aggregated_name); 393 tomoyo_put_name(e.aggregated_name);
396 return error; 394 return error;
397 } 395 }
398 396
399 /** 397 /**
400 * tomoyo_find_namespace - Find specified namespace. 398 * tomoyo_find_namespace - Find specified namespace.
401 * 399 *
402 * @name: Name of namespace to find. 400 * @name: Name of namespace to find.
403 * @len: Length of @name. 401 * @len: Length of @name.
404 * 402 *
405 * Returns pointer to "struct tomoyo_policy_namespace" if found, 403 * Returns pointer to "struct tomoyo_policy_namespace" if found,
406 * NULL otherwise. 404 * NULL otherwise.
407 * 405 *
408 * Caller holds tomoyo_read_lock(). 406 * Caller holds tomoyo_read_lock().
409 */ 407 */
410 static struct tomoyo_policy_namespace *tomoyo_find_namespace 408 static struct tomoyo_policy_namespace *tomoyo_find_namespace
411 (const char *name, const unsigned int len) 409 (const char *name, const unsigned int len)
412 { 410 {
413 struct tomoyo_policy_namespace *ns; 411 struct tomoyo_policy_namespace *ns;
414 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 412 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
415 if (strncmp(name, ns->name, len) || 413 if (strncmp(name, ns->name, len) ||
416 (name[len] && name[len] != ' ')) 414 (name[len] && name[len] != ' '))
417 continue; 415 continue;
418 return ns; 416 return ns;
419 } 417 }
420 return NULL; 418 return NULL;
421 } 419 }
422 420
423 /** 421 /**
424 * tomoyo_assign_namespace - Create a new namespace. 422 * tomoyo_assign_namespace - Create a new namespace.
425 * 423 *
426 * @domainname: Name of namespace to create. 424 * @domainname: Name of namespace to create.
427 * 425 *
428 * Returns pointer to "struct tomoyo_policy_namespace" on success, 426 * Returns pointer to "struct tomoyo_policy_namespace" on success,
429 * NULL otherwise. 427 * NULL otherwise.
430 * 428 *
431 * Caller holds tomoyo_read_lock(). 429 * Caller holds tomoyo_read_lock().
432 */ 430 */
433 struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname) 431 struct tomoyo_policy_namespace *tomoyo_assign_namespace(const char *domainname)
434 { 432 {
435 struct tomoyo_policy_namespace *ptr; 433 struct tomoyo_policy_namespace *ptr;
436 struct tomoyo_policy_namespace *entry; 434 struct tomoyo_policy_namespace *entry;
437 const char *cp = domainname; 435 const char *cp = domainname;
438 unsigned int len = 0; 436 unsigned int len = 0;
439 while (*cp && *cp++ != ' ') 437 while (*cp && *cp++ != ' ')
440 len++; 438 len++;
441 ptr = tomoyo_find_namespace(domainname, len); 439 ptr = tomoyo_find_namespace(domainname, len);
442 if (ptr) 440 if (ptr)
443 return ptr; 441 return ptr;
444 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname)) 442 if (len >= TOMOYO_EXEC_TMPSIZE - 10 || !tomoyo_domain_def(domainname))
445 return NULL; 443 return NULL;
446 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS); 444 entry = kzalloc(sizeof(*entry) + len + 1, GFP_NOFS);
447 if (!entry) 445 if (!entry)
448 return NULL; 446 return NULL;
449 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 447 if (mutex_lock_interruptible(&tomoyo_policy_lock))
450 goto out; 448 goto out;
451 ptr = tomoyo_find_namespace(domainname, len); 449 ptr = tomoyo_find_namespace(domainname, len);
452 if (!ptr && tomoyo_memory_ok(entry)) { 450 if (!ptr && tomoyo_memory_ok(entry)) {
453 char *name = (char *) (entry + 1); 451 char *name = (char *) (entry + 1);
454 ptr = entry; 452 ptr = entry;
455 memmove(name, domainname, len); 453 memmove(name, domainname, len);
456 name[len] = '\0'; 454 name[len] = '\0';
457 entry->name = name; 455 entry->name = name;
458 tomoyo_init_policy_namespace(entry); 456 tomoyo_init_policy_namespace(entry);
459 entry = NULL; 457 entry = NULL;
460 } 458 }
461 mutex_unlock(&tomoyo_policy_lock); 459 mutex_unlock(&tomoyo_policy_lock);
462 out: 460 out:
463 kfree(entry); 461 kfree(entry);
464 return ptr; 462 return ptr;
465 } 463 }
466 464
467 /** 465 /**
468 * tomoyo_namespace_jump - Check for namespace jump. 466 * tomoyo_namespace_jump - Check for namespace jump.
469 * 467 *
470 * @domainname: Name of domain. 468 * @domainname: Name of domain.
471 * 469 *
472 * Returns true if namespace differs, false otherwise. 470 * Returns true if namespace differs, false otherwise.
473 */ 471 */
474 static bool tomoyo_namespace_jump(const char *domainname) 472 static bool tomoyo_namespace_jump(const char *domainname)
475 { 473 {
476 const char *namespace = tomoyo_current_namespace()->name; 474 const char *namespace = tomoyo_current_namespace()->name;
477 const int len = strlen(namespace); 475 const int len = strlen(namespace);
478 return strncmp(domainname, namespace, len) || 476 return strncmp(domainname, namespace, len) ||
479 (domainname[len] && domainname[len] != ' '); 477 (domainname[len] && domainname[len] != ' ');
480 } 478 }
481 479
482 /** 480 /**
483 * tomoyo_assign_domain - Create a domain or a namespace. 481 * tomoyo_assign_domain - Create a domain or a namespace.
484 * 482 *
485 * @domainname: The name of domain. 483 * @domainname: The name of domain.
486 * @transit: True if transit to domain found or created. 484 * @transit: True if transit to domain found or created.
487 * 485 *
488 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 486 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
489 * 487 *
490 * Caller holds tomoyo_read_lock(). 488 * Caller holds tomoyo_read_lock().
491 */ 489 */
492 struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, 490 struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname,
493 const bool transit) 491 const bool transit)
494 { 492 {
495 struct tomoyo_domain_info e = { }; 493 struct tomoyo_domain_info e = { };
496 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname); 494 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
497 bool created = false; 495 bool created = false;
498 if (entry) { 496 if (entry) {
499 if (transit) { 497 if (transit) {
500 /* 498 /*
501 * Since namespace is created at runtime, profiles may 499 * Since namespace is created at runtime, profiles may
502 * not be created by the moment the process transits to 500 * not be created by the moment the process transits to
503 * that domain. Do not perform domain transition if 501 * that domain. Do not perform domain transition if
504 * profile for that domain is not yet created. 502 * profile for that domain is not yet created.
505 */ 503 */
506 if (!entry->ns->profile_ptr[entry->profile]) 504 if (!entry->ns->profile_ptr[entry->profile])
507 return NULL; 505 return NULL;
508 } 506 }
509 return entry; 507 return entry;
510 } 508 }
511 /* Requested domain does not exist. */ 509 /* Requested domain does not exist. */
512 /* Don't create requested domain if domainname is invalid. */ 510 /* Don't create requested domain if domainname is invalid. */
513 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 || 511 if (strlen(domainname) >= TOMOYO_EXEC_TMPSIZE - 10 ||
514 !tomoyo_correct_domain(domainname)) 512 !tomoyo_correct_domain(domainname))
515 return NULL; 513 return NULL;
516 /* 514 /*
517 * Since definition of profiles and acl_groups may differ across 515 * Since definition of profiles and acl_groups may differ across
518 * namespaces, do not inherit "use_profile" and "use_group" settings 516 * namespaces, do not inherit "use_profile" and "use_group" settings
519 * by automatically creating requested domain upon domain transition. 517 * by automatically creating requested domain upon domain transition.
520 */ 518 */
521 if (transit && tomoyo_namespace_jump(domainname)) 519 if (transit && tomoyo_namespace_jump(domainname))
522 return NULL; 520 return NULL;
523 e.ns = tomoyo_assign_namespace(domainname); 521 e.ns = tomoyo_assign_namespace(domainname);
524 if (!e.ns) 522 if (!e.ns)
525 return NULL; 523 return NULL;
526 /* 524 /*
527 * "use_profile" and "use_group" settings for automatically created 525 * "use_profile" and "use_group" settings for automatically created
528 * domains are inherited from current domain. These are 0 for manually 526 * domains are inherited from current domain. These are 0 for manually
529 * created domains. 527 * created domains.
530 */ 528 */
531 if (transit) { 529 if (transit) {
532 const struct tomoyo_domain_info *domain = tomoyo_domain(); 530 const struct tomoyo_domain_info *domain = tomoyo_domain();
533 e.profile = domain->profile; 531 e.profile = domain->profile;
534 e.group = domain->group; 532 e.group = domain->group;
535 } 533 }
536 e.domainname = tomoyo_get_name(domainname); 534 e.domainname = tomoyo_get_name(domainname);
537 if (!e.domainname) 535 if (!e.domainname)
538 return NULL; 536 return NULL;
539 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 537 if (mutex_lock_interruptible(&tomoyo_policy_lock))
540 goto out; 538 goto out;
541 entry = tomoyo_find_domain(domainname); 539 entry = tomoyo_find_domain(domainname);
542 if (!entry) { 540 if (!entry) {
543 entry = tomoyo_commit_ok(&e, sizeof(e)); 541 entry = tomoyo_commit_ok(&e, sizeof(e));
544 if (entry) { 542 if (entry) {
545 INIT_LIST_HEAD(&entry->acl_info_list); 543 INIT_LIST_HEAD(&entry->acl_info_list);
546 list_add_tail_rcu(&entry->list, &tomoyo_domain_list); 544 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
547 created = true; 545 created = true;
548 } 546 }
549 } 547 }
550 mutex_unlock(&tomoyo_policy_lock); 548 mutex_unlock(&tomoyo_policy_lock);
551 out: 549 out:
552 tomoyo_put_name(e.domainname); 550 tomoyo_put_name(e.domainname);
553 if (entry && transit) { 551 if (entry && transit) {
554 if (created) { 552 if (created) {
555 struct tomoyo_request_info r; 553 struct tomoyo_request_info r;
556 tomoyo_init_request_info(&r, entry, 554 tomoyo_init_request_info(&r, entry,
557 TOMOYO_MAC_FILE_EXECUTE); 555 TOMOYO_MAC_FILE_EXECUTE);
558 r.granted = false; 556 r.granted = false;
559 tomoyo_write_log(&r, "use_profile %u\n", 557 tomoyo_write_log(&r, "use_profile %u\n",
560 entry->profile); 558 entry->profile);
561 tomoyo_write_log(&r, "use_group %u\n", entry->group); 559 tomoyo_write_log(&r, "use_group %u\n", entry->group);
562 } 560 }
563 } 561 }
564 return entry; 562 return entry;
565 } 563 }
566 564
567 /** 565 /**
568 * tomoyo_find_next_domain - Find a domain. 566 * tomoyo_find_next_domain - Find a domain.
569 * 567 *
570 * @bprm: Pointer to "struct linux_binprm". 568 * @bprm: Pointer to "struct linux_binprm".
571 * 569 *
572 * Returns 0 on success, negative value otherwise. 570 * Returns 0 on success, negative value otherwise.
573 * 571 *
574 * Caller holds tomoyo_read_lock(). 572 * Caller holds tomoyo_read_lock().
575 */ 573 */
576 int tomoyo_find_next_domain(struct linux_binprm *bprm) 574 int tomoyo_find_next_domain(struct linux_binprm *bprm)
577 { 575 {
578 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 576 struct tomoyo_domain_info *old_domain = tomoyo_domain();
579 struct tomoyo_domain_info *domain = NULL; 577 struct tomoyo_domain_info *domain = NULL;
580 const char *original_name = bprm->filename; 578 const char *original_name = bprm->filename;
581 int retval = -ENOMEM; 579 int retval = -ENOMEM;
582 bool need_kfree = false; 580 bool need_kfree = false;
583 bool reject_on_transition_failure = false; 581 bool reject_on_transition_failure = false;
584 struct tomoyo_path_info rn = { }; /* real name */ 582 struct tomoyo_path_info rn = { }; /* real name */
585 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS); 583 struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS);
586 if (!ee) 584 if (!ee)
587 return -ENOMEM; 585 return -ENOMEM;
588 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); 586 ee->tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
589 if (!ee->tmp) { 587 if (!ee->tmp) {
590 kfree(ee); 588 kfree(ee);
591 return -ENOMEM; 589 return -ENOMEM;
592 } 590 }
593 /* ee->dump->data is allocated by tomoyo_dump_page(). */ 591 /* ee->dump->data is allocated by tomoyo_dump_page(). */
594 tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE); 592 tomoyo_init_request_info(&ee->r, NULL, TOMOYO_MAC_FILE_EXECUTE);
595 ee->r.ee = ee; 593 ee->r.ee = ee;
596 ee->bprm = bprm; 594 ee->bprm = bprm;
597 ee->r.obj = &ee->obj; 595 ee->r.obj = &ee->obj;
598 ee->obj.path1 = bprm->file->f_path; 596 ee->obj.path1 = bprm->file->f_path;
599 retry: 597 retry:
600 if (need_kfree) { 598 if (need_kfree) {
601 kfree(rn.name); 599 kfree(rn.name);
602 need_kfree = false; 600 need_kfree = false;
603 } 601 }
604 /* Get symlink's pathname of program. */ 602 /* Get symlink's pathname of program. */
605 retval = -ENOENT; 603 retval = -ENOENT;
606 rn.name = tomoyo_realpath_nofollow(original_name); 604 rn.name = tomoyo_realpath_nofollow(original_name);
607 if (!rn.name) 605 if (!rn.name)
608 goto out; 606 goto out;
609 tomoyo_fill_path_info(&rn); 607 tomoyo_fill_path_info(&rn);
610 need_kfree = true; 608 need_kfree = true;
611 609
612 /* Check 'aggregator' directive. */ 610 /* Check 'aggregator' directive. */
613 { 611 {
614 struct tomoyo_aggregator *ptr; 612 struct tomoyo_aggregator *ptr;
615 struct list_head *list = 613 struct list_head *list =
616 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR]; 614 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
617 /* Check 'aggregator' directive. */ 615 /* Check 'aggregator' directive. */
618 list_for_each_entry_rcu(ptr, list, head.list) { 616 list_for_each_entry_rcu(ptr, list, head.list) {
619 if (ptr->head.is_deleted || 617 if (ptr->head.is_deleted ||
620 !tomoyo_path_matches_pattern(&rn, 618 !tomoyo_path_matches_pattern(&rn,
621 ptr->original_name)) 619 ptr->original_name))
622 continue; 620 continue;
623 kfree(rn.name); 621 kfree(rn.name);
624 need_kfree = false; 622 need_kfree = false;
625 /* This is OK because it is read only. */ 623 /* This is OK because it is read only. */
626 rn = *ptr->aggregated_name; 624 rn = *ptr->aggregated_name;
627 break; 625 break;
628 } 626 }
629 } 627 }
630 628
631 /* Check execute permission. */ 629 /* Check execute permission. */
632 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn); 630 retval = tomoyo_path_permission(&ee->r, TOMOYO_TYPE_EXECUTE, &rn);
633 if (retval == TOMOYO_RETRY_REQUEST) 631 if (retval == TOMOYO_RETRY_REQUEST)
634 goto retry; 632 goto retry;
635 if (retval < 0) 633 if (retval < 0)
636 goto out; 634 goto out;
637 /* 635 /*
638 * To be able to specify domainnames with wildcards, use the 636 * To be able to specify domainnames with wildcards, use the
639 * pathname specified in the policy (which may contain 637 * pathname specified in the policy (which may contain
640 * wildcard) rather than the pathname passed to execve() 638 * wildcard) rather than the pathname passed to execve()
641 * (which never contains wildcard). 639 * (which never contains wildcard).
642 */ 640 */
643 if (ee->r.param.path.matched_path) { 641 if (ee->r.param.path.matched_path) {
644 if (need_kfree) 642 if (need_kfree)
645 kfree(rn.name); 643 kfree(rn.name);
646 need_kfree = false; 644 need_kfree = false;
647 /* This is OK because it is read only. */ 645 /* This is OK because it is read only. */
648 rn = *ee->r.param.path.matched_path; 646 rn = *ee->r.param.path.matched_path;
649 } 647 }
650 648
651 /* Calculate domain to transit to. */ 649 /* Calculate domain to transit to. */
652 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname, 650 switch (tomoyo_transition_type(old_domain->ns, old_domain->domainname,
653 &rn)) { 651 &rn)) {
654 case TOMOYO_TRANSITION_CONTROL_RESET: 652 case TOMOYO_TRANSITION_CONTROL_RESET:
655 /* Transit to the root of specified namespace. */ 653 /* Transit to the root of specified namespace. */
656 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name); 654 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>", rn.name);
657 /* 655 /*
658 * Make do_execve() fail if domain transition across namespaces 656 * Make do_execve() fail if domain transition across namespaces
659 * has failed. 657 * has failed.
660 */ 658 */
661 reject_on_transition_failure = true; 659 reject_on_transition_failure = true;
662 break; 660 break;
663 case TOMOYO_TRANSITION_CONTROL_INITIALIZE: 661 case TOMOYO_TRANSITION_CONTROL_INITIALIZE:
664 /* Transit to the child of current namespace's root. */ 662 /* Transit to the child of current namespace's root. */
665 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 663 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
666 old_domain->ns->name, rn.name); 664 old_domain->ns->name, rn.name);
667 break; 665 break;
668 case TOMOYO_TRANSITION_CONTROL_KEEP: 666 case TOMOYO_TRANSITION_CONTROL_KEEP:
669 /* Keep current domain. */ 667 /* Keep current domain. */
670 domain = old_domain; 668 domain = old_domain;
671 break; 669 break;
672 default: 670 default:
673 if (old_domain == &tomoyo_kernel_domain && 671 if (old_domain == &tomoyo_kernel_domain &&
674 !tomoyo_policy_loaded) { 672 !tomoyo_policy_loaded) {
675 /* 673 /*
676 * Needn't to transit from kernel domain before 674 * Needn't to transit from kernel domain before
677 * starting /sbin/init. But transit from kernel domain 675 * starting /sbin/init. But transit from kernel domain
678 * if executing initializers because they might start 676 * if executing initializers because they might start
679 * before /sbin/init. 677 * before /sbin/init.
680 */ 678 */
681 domain = old_domain; 679 domain = old_domain;
682 } else { 680 } else {
683 /* Normal domain transition. */ 681 /* Normal domain transition. */
684 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", 682 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s",
685 old_domain->domainname->name, rn.name); 683 old_domain->domainname->name, rn.name);
686 } 684 }
687 break; 685 break;
688 } 686 }
689 if (!domain) 687 if (!domain)
690 domain = tomoyo_assign_domain(ee->tmp, true); 688 domain = tomoyo_assign_domain(ee->tmp, true);
691 if (domain) 689 if (domain)
692 retval = 0; 690 retval = 0;
693 else if (reject_on_transition_failure) { 691 else if (reject_on_transition_failure) {
694 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", 692 printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n",
695 ee->tmp); 693 ee->tmp);
696 retval = -ENOMEM; 694 retval = -ENOMEM;
697 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING) 695 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
698 retval = -ENOMEM; 696 retval = -ENOMEM;
699 else { 697 else {
700 retval = 0; 698 retval = 0;
701 if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) { 699 if (!old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED]) {
702 old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true; 700 old_domain->flags[TOMOYO_DIF_TRANSITION_FAILED] = true;
703 ee->r.granted = false; 701 ee->r.granted = false;
704 tomoyo_write_log(&ee->r, "%s", tomoyo_dif 702 tomoyo_write_log(&ee->r, "%s", tomoyo_dif
705 [TOMOYO_DIF_TRANSITION_FAILED]); 703 [TOMOYO_DIF_TRANSITION_FAILED]);
706 printk(KERN_WARNING 704 printk(KERN_WARNING
707 "ERROR: Domain '%s' not defined.\n", ee->tmp); 705 "ERROR: Domain '%s' not defined.\n", ee->tmp);
708 } 706 }
709 } 707 }
710 out: 708 out:
711 if (!domain) 709 if (!domain)
712 domain = old_domain; 710 domain = old_domain;
713 /* Update reference count on "struct tomoyo_domain_info". */ 711 /* Update reference count on "struct tomoyo_domain_info". */
714 atomic_inc(&domain->users); 712 atomic_inc(&domain->users);
715 bprm->cred->security = domain; 713 bprm->cred->security = domain;
716 if (need_kfree) 714 if (need_kfree)
717 kfree(rn.name); 715 kfree(rn.name);
718 kfree(ee->tmp); 716 kfree(ee->tmp);
719 kfree(ee->dump.data); 717 kfree(ee->dump.data);
720 kfree(ee); 718 kfree(ee);
721 return retval; 719 return retval;
722 } 720 }
723 721
724 /** 722 /**
725 * tomoyo_dump_page - Dump a page to buffer. 723 * tomoyo_dump_page - Dump a page to buffer.
726 * 724 *
727 * @bprm: Pointer to "struct linux_binprm". 725 * @bprm: Pointer to "struct linux_binprm".
728 * @pos: Location to dump. 726 * @pos: Location to dump.
729 * @dump: Poiner to "struct tomoyo_page_dump". 727 * @dump: Poiner to "struct tomoyo_page_dump".
730 * 728 *
731 * Returns true on success, false otherwise. 729 * Returns true on success, false otherwise.
732 */ 730 */
733 bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, 731 bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
734 struct tomoyo_page_dump *dump) 732 struct tomoyo_page_dump *dump)
735 { 733 {
736 struct page *page; 734 struct page *page;
737 /* dump->data is released by tomoyo_finish_execve(). */ 735 /* dump->data is released by tomoyo_finish_execve(). */
738 if (!dump->data) { 736 if (!dump->data) {
739 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS); 737 dump->data = kzalloc(PAGE_SIZE, GFP_NOFS);
740 if (!dump->data) 738 if (!dump->data)
741 return false; 739 return false;
742 } 740 }
743 /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */ 741 /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
744 #ifdef CONFIG_MMU 742 #ifdef CONFIG_MMU
745 if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) 743 if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
746 return false; 744 return false;
747 #else 745 #else
748 page = bprm->page[pos / PAGE_SIZE]; 746 page = bprm->page[pos / PAGE_SIZE];
749 #endif 747 #endif
750 if (page != dump->page) { 748 if (page != dump->page) {
751 const unsigned int offset = pos % PAGE_SIZE; 749 const unsigned int offset = pos % PAGE_SIZE;
752 /* 750 /*
753 * Maybe kmap()/kunmap() should be used here. 751 * Maybe kmap()/kunmap() should be used here.
754 * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic(). 752 * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
755 * So do I. 753 * So do I.
756 */ 754 */
757 char *kaddr = kmap_atomic(page, KM_USER0); 755 char *kaddr = kmap_atomic(page, KM_USER0);
758 dump->page = page; 756 dump->page = page;
759 memcpy(dump->data + offset, kaddr + offset, 757 memcpy(dump->data + offset, kaddr + offset,
760 PAGE_SIZE - offset); 758 PAGE_SIZE - offset);
761 kunmap_atomic(kaddr, KM_USER0); 759 kunmap_atomic(kaddr, KM_USER0);
762 } 760 }
763 /* Same with put_arg_page(page) in fs/exec.c */ 761 /* Same with put_arg_page(page) in fs/exec.c */
764 #ifdef CONFIG_MMU 762 #ifdef CONFIG_MMU
765 put_page(page); 763 put_page(page);
766 #endif 764 #endif
767 return true; 765 return true;
768 } 766 }
769 767
security/tomoyo/file.c
1 /* 1 /*
2 * security/tomoyo/file.c 2 * security/tomoyo/file.c
3 * 3 *
4 * Pathname restriction functions. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include "common.h" 7 #include "common.h"
10 #include <linux/slab.h> 8 #include <linux/slab.h>
11 9
12 /* 10 /*
13 * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index". 11 * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
14 */ 12 */
15 static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = { 13 static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
16 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE, 14 [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
17 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN, 15 [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
18 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN, 16 [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
19 [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN, 17 [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
20 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK, 18 [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
21 [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR, 19 [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
22 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR, 20 [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
23 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE, 21 [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
24 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK, 22 [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
25 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT, 23 [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
26 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT, 24 [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
27 }; 25 };
28 26
29 /* 27 /*
30 * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index". 28 * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
31 */ 29 */
32 const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = { 30 const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
33 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK, 31 [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
34 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR, 32 [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
35 }; 33 };
36 34
37 /* 35 /*
38 * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index". 36 * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
39 */ 37 */
40 const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = { 38 const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
41 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK, 39 [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
42 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME, 40 [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
43 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT, 41 [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
44 }; 42 };
45 43
46 /* 44 /*
47 * Mapping table from "enum tomoyo_path_number_acl_index" to 45 * Mapping table from "enum tomoyo_path_number_acl_index" to
48 * "enum tomoyo_mac_index". 46 * "enum tomoyo_mac_index".
49 */ 47 */
50 const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = { 48 const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
51 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE, 49 [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
52 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR, 50 [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
53 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO, 51 [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
54 [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK, 52 [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
55 [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL, 53 [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL,
56 [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD, 54 [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD,
57 [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN, 55 [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN,
58 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP, 56 [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
59 }; 57 };
60 58
61 /** 59 /**
62 * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union". 60 * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
63 * 61 *
64 * @ptr: Pointer to "struct tomoyo_name_union". 62 * @ptr: Pointer to "struct tomoyo_name_union".
65 * 63 *
66 * Returns nothing. 64 * Returns nothing.
67 */ 65 */
68 void tomoyo_put_name_union(struct tomoyo_name_union *ptr) 66 void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
69 { 67 {
70 tomoyo_put_group(ptr->group); 68 tomoyo_put_group(ptr->group);
71 tomoyo_put_name(ptr->filename); 69 tomoyo_put_name(ptr->filename);
72 } 70 }
73 71
74 /** 72 /**
75 * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not. 73 * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
76 * 74 *
77 * @name: Pointer to "struct tomoyo_path_info". 75 * @name: Pointer to "struct tomoyo_path_info".
78 * @ptr: Pointer to "struct tomoyo_name_union". 76 * @ptr: Pointer to "struct tomoyo_name_union".
79 * 77 *
80 * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise. 78 * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
81 */ 79 */
82 const struct tomoyo_path_info * 80 const struct tomoyo_path_info *
83 tomoyo_compare_name_union(const struct tomoyo_path_info *name, 81 tomoyo_compare_name_union(const struct tomoyo_path_info *name,
84 const struct tomoyo_name_union *ptr) 82 const struct tomoyo_name_union *ptr)
85 { 83 {
86 if (ptr->group) 84 if (ptr->group)
87 return tomoyo_path_matches_group(name, ptr->group); 85 return tomoyo_path_matches_group(name, ptr->group);
88 if (tomoyo_path_matches_pattern(name, ptr->filename)) 86 if (tomoyo_path_matches_pattern(name, ptr->filename))
89 return ptr->filename; 87 return ptr->filename;
90 return NULL; 88 return NULL;
91 } 89 }
92 90
93 /** 91 /**
94 * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union". 92 * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
95 * 93 *
96 * @ptr: Pointer to "struct tomoyo_number_union". 94 * @ptr: Pointer to "struct tomoyo_number_union".
97 * 95 *
98 * Returns nothing. 96 * Returns nothing.
99 */ 97 */
100 void tomoyo_put_number_union(struct tomoyo_number_union *ptr) 98 void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
101 { 99 {
102 tomoyo_put_group(ptr->group); 100 tomoyo_put_group(ptr->group);
103 } 101 }
104 102
105 /** 103 /**
106 * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not. 104 * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
107 * 105 *
108 * @value: Number to check. 106 * @value: Number to check.
109 * @ptr: Pointer to "struct tomoyo_number_union". 107 * @ptr: Pointer to "struct tomoyo_number_union".
110 * 108 *
111 * Returns true if @value matches @ptr, false otherwise. 109 * Returns true if @value matches @ptr, false otherwise.
112 */ 110 */
113 bool tomoyo_compare_number_union(const unsigned long value, 111 bool tomoyo_compare_number_union(const unsigned long value,
114 const struct tomoyo_number_union *ptr) 112 const struct tomoyo_number_union *ptr)
115 { 113 {
116 if (ptr->group) 114 if (ptr->group)
117 return tomoyo_number_matches_group(value, value, ptr->group); 115 return tomoyo_number_matches_group(value, value, ptr->group);
118 return value >= ptr->values[0] && value <= ptr->values[1]; 116 return value >= ptr->values[0] && value <= ptr->values[1];
119 } 117 }
120 118
121 /** 119 /**
122 * tomoyo_add_slash - Add trailing '/' if needed. 120 * tomoyo_add_slash - Add trailing '/' if needed.
123 * 121 *
124 * @buf: Pointer to "struct tomoyo_path_info". 122 * @buf: Pointer to "struct tomoyo_path_info".
125 * 123 *
126 * Returns nothing. 124 * Returns nothing.
127 * 125 *
128 * @buf must be generated by tomoyo_encode() because this function does not 126 * @buf must be generated by tomoyo_encode() because this function does not
129 * allocate memory for adding '/'. 127 * allocate memory for adding '/'.
130 */ 128 */
131 static void tomoyo_add_slash(struct tomoyo_path_info *buf) 129 static void tomoyo_add_slash(struct tomoyo_path_info *buf)
132 { 130 {
133 if (buf->is_dir) 131 if (buf->is_dir)
134 return; 132 return;
135 /* 133 /*
136 * This is OK because tomoyo_encode() reserves space for appending "/". 134 * This is OK because tomoyo_encode() reserves space for appending "/".
137 */ 135 */
138 strcat((char *) buf->name, "/"); 136 strcat((char *) buf->name, "/");
139 tomoyo_fill_path_info(buf); 137 tomoyo_fill_path_info(buf);
140 } 138 }
141 139
142 /** 140 /**
143 * tomoyo_get_realpath - Get realpath. 141 * tomoyo_get_realpath - Get realpath.
144 * 142 *
145 * @buf: Pointer to "struct tomoyo_path_info". 143 * @buf: Pointer to "struct tomoyo_path_info".
146 * @path: Pointer to "struct path". 144 * @path: Pointer to "struct path".
147 * 145 *
148 * Returns true on success, false otherwise. 146 * Returns true on success, false otherwise.
149 */ 147 */
150 static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path) 148 static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
151 { 149 {
152 buf->name = tomoyo_realpath_from_path(path); 150 buf->name = tomoyo_realpath_from_path(path);
153 if (buf->name) { 151 if (buf->name) {
154 tomoyo_fill_path_info(buf); 152 tomoyo_fill_path_info(buf);
155 return true; 153 return true;
156 } 154 }
157 return false; 155 return false;
158 } 156 }
159 157
160 /** 158 /**
161 * tomoyo_audit_path_log - Audit path request log. 159 * tomoyo_audit_path_log - Audit path request log.
162 * 160 *
163 * @r: Pointer to "struct tomoyo_request_info". 161 * @r: Pointer to "struct tomoyo_request_info".
164 * 162 *
165 * Returns 0 on success, negative value otherwise. 163 * Returns 0 on success, negative value otherwise.
166 */ 164 */
167 static int tomoyo_audit_path_log(struct tomoyo_request_info *r) 165 static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
168 { 166 {
169 return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword 167 return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
170 [r->param.path.operation], 168 [r->param.path.operation],
171 r->param.path.filename->name); 169 r->param.path.filename->name);
172 } 170 }
173 171
174 /** 172 /**
175 * tomoyo_audit_path2_log - Audit path/path request log. 173 * tomoyo_audit_path2_log - Audit path/path request log.
176 * 174 *
177 * @r: Pointer to "struct tomoyo_request_info". 175 * @r: Pointer to "struct tomoyo_request_info".
178 * 176 *
179 * Returns 0 on success, negative value otherwise. 177 * Returns 0 on success, negative value otherwise.
180 */ 178 */
181 static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) 179 static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
182 { 180 {
183 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords 181 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
184 [tomoyo_pp2mac[r->param.path2.operation]], 182 [tomoyo_pp2mac[r->param.path2.operation]],
185 r->param.path2.filename1->name, 183 r->param.path2.filename1->name,
186 r->param.path2.filename2->name); 184 r->param.path2.filename2->name);
187 } 185 }
188 186
189 /** 187 /**
190 * tomoyo_audit_mkdev_log - Audit path/number/number/number request log. 188 * tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
191 * 189 *
192 * @r: Pointer to "struct tomoyo_request_info". 190 * @r: Pointer to "struct tomoyo_request_info".
193 * 191 *
194 * Returns 0 on success, negative value otherwise. 192 * Returns 0 on success, negative value otherwise.
195 */ 193 */
196 static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) 194 static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
197 { 195 {
198 return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n", 196 return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
199 tomoyo_mac_keywords 197 tomoyo_mac_keywords
200 [tomoyo_pnnn2mac[r->param.mkdev.operation]], 198 [tomoyo_pnnn2mac[r->param.mkdev.operation]],
201 r->param.mkdev.filename->name, 199 r->param.mkdev.filename->name,
202 r->param.mkdev.mode, r->param.mkdev.major, 200 r->param.mkdev.mode, r->param.mkdev.major,
203 r->param.mkdev.minor); 201 r->param.mkdev.minor);
204 } 202 }
205 203
206 /** 204 /**
207 * tomoyo_audit_path_number_log - Audit path/number request log. 205 * tomoyo_audit_path_number_log - Audit path/number request log.
208 * 206 *
209 * @r: Pointer to "struct tomoyo_request_info". 207 * @r: Pointer to "struct tomoyo_request_info".
210 * 208 *
211 * Returns 0 on success, negative value otherwise. 209 * Returns 0 on success, negative value otherwise.
212 */ 210 */
213 static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r) 211 static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
214 { 212 {
215 const u8 type = r->param.path_number.operation; 213 const u8 type = r->param.path_number.operation;
216 u8 radix; 214 u8 radix;
217 char buffer[64]; 215 char buffer[64];
218 switch (type) { 216 switch (type) {
219 case TOMOYO_TYPE_CREATE: 217 case TOMOYO_TYPE_CREATE:
220 case TOMOYO_TYPE_MKDIR: 218 case TOMOYO_TYPE_MKDIR:
221 case TOMOYO_TYPE_MKFIFO: 219 case TOMOYO_TYPE_MKFIFO:
222 case TOMOYO_TYPE_MKSOCK: 220 case TOMOYO_TYPE_MKSOCK:
223 case TOMOYO_TYPE_CHMOD: 221 case TOMOYO_TYPE_CHMOD:
224 radix = TOMOYO_VALUE_TYPE_OCTAL; 222 radix = TOMOYO_VALUE_TYPE_OCTAL;
225 break; 223 break;
226 case TOMOYO_TYPE_IOCTL: 224 case TOMOYO_TYPE_IOCTL:
227 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL; 225 radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
228 break; 226 break;
229 default: 227 default:
230 radix = TOMOYO_VALUE_TYPE_DECIMAL; 228 radix = TOMOYO_VALUE_TYPE_DECIMAL;
231 break; 229 break;
232 } 230 }
233 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number, 231 tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
234 radix); 232 radix);
235 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords 233 return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
236 [tomoyo_pn2mac[type]], 234 [tomoyo_pn2mac[type]],
237 r->param.path_number.filename->name, buffer); 235 r->param.path_number.filename->name, buffer);
238 } 236 }
239 237
240 /** 238 /**
241 * tomoyo_check_path_acl - Check permission for path operation. 239 * tomoyo_check_path_acl - Check permission for path operation.
242 * 240 *
243 * @r: Pointer to "struct tomoyo_request_info". 241 * @r: Pointer to "struct tomoyo_request_info".
244 * @ptr: Pointer to "struct tomoyo_acl_info". 242 * @ptr: Pointer to "struct tomoyo_acl_info".
245 * 243 *
246 * Returns true if granted, false otherwise. 244 * Returns true if granted, false otherwise.
247 * 245 *
248 * To be able to use wildcard for domain transition, this function sets 246 * To be able to use wildcard for domain transition, this function sets
249 * matching entry on success. Since the caller holds tomoyo_read_lock(), 247 * matching entry on success. Since the caller holds tomoyo_read_lock(),
250 * it is safe to set matching entry. 248 * it is safe to set matching entry.
251 */ 249 */
252 static bool tomoyo_check_path_acl(struct tomoyo_request_info *r, 250 static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
253 const struct tomoyo_acl_info *ptr) 251 const struct tomoyo_acl_info *ptr)
254 { 252 {
255 const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), 253 const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
256 head); 254 head);
257 if (acl->perm & (1 << r->param.path.operation)) { 255 if (acl->perm & (1 << r->param.path.operation)) {
258 r->param.path.matched_path = 256 r->param.path.matched_path =
259 tomoyo_compare_name_union(r->param.path.filename, 257 tomoyo_compare_name_union(r->param.path.filename,
260 &acl->name); 258 &acl->name);
261 return r->param.path.matched_path != NULL; 259 return r->param.path.matched_path != NULL;
262 } 260 }
263 return false; 261 return false;
264 } 262 }
265 263
266 /** 264 /**
267 * tomoyo_check_path_number_acl - Check permission for path number operation. 265 * tomoyo_check_path_number_acl - Check permission for path number operation.
268 * 266 *
269 * @r: Pointer to "struct tomoyo_request_info". 267 * @r: Pointer to "struct tomoyo_request_info".
270 * @ptr: Pointer to "struct tomoyo_acl_info". 268 * @ptr: Pointer to "struct tomoyo_acl_info".
271 * 269 *
272 * Returns true if granted, false otherwise. 270 * Returns true if granted, false otherwise.
273 */ 271 */
274 static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r, 272 static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
275 const struct tomoyo_acl_info *ptr) 273 const struct tomoyo_acl_info *ptr)
276 { 274 {
277 const struct tomoyo_path_number_acl *acl = 275 const struct tomoyo_path_number_acl *acl =
278 container_of(ptr, typeof(*acl), head); 276 container_of(ptr, typeof(*acl), head);
279 return (acl->perm & (1 << r->param.path_number.operation)) && 277 return (acl->perm & (1 << r->param.path_number.operation)) &&
280 tomoyo_compare_number_union(r->param.path_number.number, 278 tomoyo_compare_number_union(r->param.path_number.number,
281 &acl->number) && 279 &acl->number) &&
282 tomoyo_compare_name_union(r->param.path_number.filename, 280 tomoyo_compare_name_union(r->param.path_number.filename,
283 &acl->name); 281 &acl->name);
284 } 282 }
285 283
286 /** 284 /**
287 * tomoyo_check_path2_acl - Check permission for path path operation. 285 * tomoyo_check_path2_acl - Check permission for path path operation.
288 * 286 *
289 * @r: Pointer to "struct tomoyo_request_info". 287 * @r: Pointer to "struct tomoyo_request_info".
290 * @ptr: Pointer to "struct tomoyo_acl_info". 288 * @ptr: Pointer to "struct tomoyo_acl_info".
291 * 289 *
292 * Returns true if granted, false otherwise. 290 * Returns true if granted, false otherwise.
293 */ 291 */
294 static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r, 292 static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
295 const struct tomoyo_acl_info *ptr) 293 const struct tomoyo_acl_info *ptr)
296 { 294 {
297 const struct tomoyo_path2_acl *acl = 295 const struct tomoyo_path2_acl *acl =
298 container_of(ptr, typeof(*acl), head); 296 container_of(ptr, typeof(*acl), head);
299 return (acl->perm & (1 << r->param.path2.operation)) && 297 return (acl->perm & (1 << r->param.path2.operation)) &&
300 tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1) 298 tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
301 && tomoyo_compare_name_union(r->param.path2.filename2, 299 && tomoyo_compare_name_union(r->param.path2.filename2,
302 &acl->name2); 300 &acl->name2);
303 } 301 }
304 302
305 /** 303 /**
306 * tomoyo_check_mkdev_acl - Check permission for path number number number operation. 304 * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
307 * 305 *
308 * @r: Pointer to "struct tomoyo_request_info". 306 * @r: Pointer to "struct tomoyo_request_info".
309 * @ptr: Pointer to "struct tomoyo_acl_info". 307 * @ptr: Pointer to "struct tomoyo_acl_info".
310 * 308 *
311 * Returns true if granted, false otherwise. 309 * Returns true if granted, false otherwise.
312 */ 310 */
313 static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r, 311 static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
314 const struct tomoyo_acl_info *ptr) 312 const struct tomoyo_acl_info *ptr)
315 { 313 {
316 const struct tomoyo_mkdev_acl *acl = 314 const struct tomoyo_mkdev_acl *acl =
317 container_of(ptr, typeof(*acl), head); 315 container_of(ptr, typeof(*acl), head);
318 return (acl->perm & (1 << r->param.mkdev.operation)) && 316 return (acl->perm & (1 << r->param.mkdev.operation)) &&
319 tomoyo_compare_number_union(r->param.mkdev.mode, 317 tomoyo_compare_number_union(r->param.mkdev.mode,
320 &acl->mode) && 318 &acl->mode) &&
321 tomoyo_compare_number_union(r->param.mkdev.major, 319 tomoyo_compare_number_union(r->param.mkdev.major,
322 &acl->major) && 320 &acl->major) &&
323 tomoyo_compare_number_union(r->param.mkdev.minor, 321 tomoyo_compare_number_union(r->param.mkdev.minor,
324 &acl->minor) && 322 &acl->minor) &&
325 tomoyo_compare_name_union(r->param.mkdev.filename, 323 tomoyo_compare_name_union(r->param.mkdev.filename,
326 &acl->name); 324 &acl->name);
327 } 325 }
328 326
329 /** 327 /**
330 * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry. 328 * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
331 * 329 *
332 * @a: Pointer to "struct tomoyo_acl_info". 330 * @a: Pointer to "struct tomoyo_acl_info".
333 * @b: Pointer to "struct tomoyo_acl_info". 331 * @b: Pointer to "struct tomoyo_acl_info".
334 * 332 *
335 * Returns true if @a == @b except permission bits, false otherwise. 333 * Returns true if @a == @b except permission bits, false otherwise.
336 */ 334 */
337 static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 335 static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
338 const struct tomoyo_acl_info *b) 336 const struct tomoyo_acl_info *b)
339 { 337 {
340 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head); 338 const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
341 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head); 339 const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
342 return tomoyo_same_name_union(&p1->name, &p2->name); 340 return tomoyo_same_name_union(&p1->name, &p2->name);
343 } 341 }
344 342
345 /** 343 /**
346 * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry. 344 * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
347 * 345 *
348 * @a: Pointer to "struct tomoyo_acl_info". 346 * @a: Pointer to "struct tomoyo_acl_info".
349 * @b: Pointer to "struct tomoyo_acl_info". 347 * @b: Pointer to "struct tomoyo_acl_info".
350 * @is_delete: True for @a &= ~@b, false for @a |= @b. 348 * @is_delete: True for @a &= ~@b, false for @a |= @b.
351 * 349 *
352 * Returns true if @a is empty, false otherwise. 350 * Returns true if @a is empty, false otherwise.
353 */ 351 */
354 static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a, 352 static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
355 struct tomoyo_acl_info *b, 353 struct tomoyo_acl_info *b,
356 const bool is_delete) 354 const bool is_delete)
357 { 355 {
358 u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head) 356 u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head)
359 ->perm; 357 ->perm;
360 u16 perm = *a_perm; 358 u16 perm = *a_perm;
361 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm; 359 const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
362 if (is_delete) 360 if (is_delete)
363 perm &= ~b_perm; 361 perm &= ~b_perm;
364 else 362 else
365 perm |= b_perm; 363 perm |= b_perm;
366 *a_perm = perm; 364 *a_perm = perm;
367 return !perm; 365 return !perm;
368 } 366 }
369 367
370 /** 368 /**
371 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list. 369 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
372 * 370 *
373 * @perm: Permission. 371 * @perm: Permission.
374 * @param: Pointer to "struct tomoyo_acl_param". 372 * @param: Pointer to "struct tomoyo_acl_param".
375 * 373 *
376 * Returns 0 on success, negative value otherwise. 374 * Returns 0 on success, negative value otherwise.
377 * 375 *
378 * Caller holds tomoyo_read_lock(). 376 * Caller holds tomoyo_read_lock().
379 */ 377 */
380 static int tomoyo_update_path_acl(const u16 perm, 378 static int tomoyo_update_path_acl(const u16 perm,
381 struct tomoyo_acl_param *param) 379 struct tomoyo_acl_param *param)
382 { 380 {
383 struct tomoyo_path_acl e = { 381 struct tomoyo_path_acl e = {
384 .head.type = TOMOYO_TYPE_PATH_ACL, 382 .head.type = TOMOYO_TYPE_PATH_ACL,
385 .perm = perm 383 .perm = perm
386 }; 384 };
387 int error; 385 int error;
388 if (!tomoyo_parse_name_union(param, &e.name)) 386 if (!tomoyo_parse_name_union(param, &e.name))
389 error = -EINVAL; 387 error = -EINVAL;
390 else 388 else
391 error = tomoyo_update_domain(&e.head, sizeof(e), param, 389 error = tomoyo_update_domain(&e.head, sizeof(e), param,
392 tomoyo_same_path_acl, 390 tomoyo_same_path_acl,
393 tomoyo_merge_path_acl); 391 tomoyo_merge_path_acl);
394 tomoyo_put_name_union(&e.name); 392 tomoyo_put_name_union(&e.name);
395 return error; 393 return error;
396 } 394 }
397 395
398 /** 396 /**
399 * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry. 397 * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
400 * 398 *
401 * @a: Pointer to "struct tomoyo_acl_info". 399 * @a: Pointer to "struct tomoyo_acl_info".
402 * @b: Pointer to "struct tomoyo_acl_info". 400 * @b: Pointer to "struct tomoyo_acl_info".
403 * 401 *
404 * Returns true if @a == @b except permission bits, false otherwise. 402 * Returns true if @a == @b except permission bits, false otherwise.
405 */ 403 */
406 static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a, 404 static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
407 const struct tomoyo_acl_info *b) 405 const struct tomoyo_acl_info *b)
408 { 406 {
409 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head); 407 const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
410 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head); 408 const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
411 return tomoyo_same_name_union(&p1->name, &p2->name) && 409 return tomoyo_same_name_union(&p1->name, &p2->name) &&
412 tomoyo_same_number_union(&p1->mode, &p2->mode) && 410 tomoyo_same_number_union(&p1->mode, &p2->mode) &&
413 tomoyo_same_number_union(&p1->major, &p2->major) && 411 tomoyo_same_number_union(&p1->major, &p2->major) &&
414 tomoyo_same_number_union(&p1->minor, &p2->minor); 412 tomoyo_same_number_union(&p1->minor, &p2->minor);
415 } 413 }
416 414
417 /** 415 /**
418 * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry. 416 * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
419 * 417 *
420 * @a: Pointer to "struct tomoyo_acl_info". 418 * @a: Pointer to "struct tomoyo_acl_info".
421 * @b: Pointer to "struct tomoyo_acl_info". 419 * @b: Pointer to "struct tomoyo_acl_info".
422 * @is_delete: True for @a &= ~@b, false for @a |= @b. 420 * @is_delete: True for @a &= ~@b, false for @a |= @b.
423 * 421 *
424 * Returns true if @a is empty, false otherwise. 422 * Returns true if @a is empty, false otherwise.
425 */ 423 */
426 static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a, 424 static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
427 struct tomoyo_acl_info *b, 425 struct tomoyo_acl_info *b,
428 const bool is_delete) 426 const bool is_delete)
429 { 427 {
430 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl, 428 u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
431 head)->perm; 429 head)->perm;
432 u8 perm = *a_perm; 430 u8 perm = *a_perm;
433 const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head) 431 const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head)
434 ->perm; 432 ->perm;
435 if (is_delete) 433 if (is_delete)
436 perm &= ~b_perm; 434 perm &= ~b_perm;
437 else 435 else
438 perm |= b_perm; 436 perm |= b_perm;
439 *a_perm = perm; 437 *a_perm = perm;
440 return !perm; 438 return !perm;
441 } 439 }
442 440
443 /** 441 /**
444 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list. 442 * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
445 * 443 *
446 * @perm: Permission. 444 * @perm: Permission.
447 * @param: Pointer to "struct tomoyo_acl_param". 445 * @param: Pointer to "struct tomoyo_acl_param".
448 * 446 *
449 * Returns 0 on success, negative value otherwise. 447 * Returns 0 on success, negative value otherwise.
450 * 448 *
451 * Caller holds tomoyo_read_lock(). 449 * Caller holds tomoyo_read_lock().
452 */ 450 */
453 static int tomoyo_update_mkdev_acl(const u8 perm, 451 static int tomoyo_update_mkdev_acl(const u8 perm,
454 struct tomoyo_acl_param *param) 452 struct tomoyo_acl_param *param)
455 { 453 {
456 struct tomoyo_mkdev_acl e = { 454 struct tomoyo_mkdev_acl e = {
457 .head.type = TOMOYO_TYPE_MKDEV_ACL, 455 .head.type = TOMOYO_TYPE_MKDEV_ACL,
458 .perm = perm 456 .perm = perm
459 }; 457 };
460 int error; 458 int error;
461 if (!tomoyo_parse_name_union(param, &e.name) || 459 if (!tomoyo_parse_name_union(param, &e.name) ||
462 !tomoyo_parse_number_union(param, &e.mode) || 460 !tomoyo_parse_number_union(param, &e.mode) ||
463 !tomoyo_parse_number_union(param, &e.major) || 461 !tomoyo_parse_number_union(param, &e.major) ||
464 !tomoyo_parse_number_union(param, &e.minor)) 462 !tomoyo_parse_number_union(param, &e.minor))
465 error = -EINVAL; 463 error = -EINVAL;
466 else 464 else
467 error = tomoyo_update_domain(&e.head, sizeof(e), param, 465 error = tomoyo_update_domain(&e.head, sizeof(e), param,
468 tomoyo_same_mkdev_acl, 466 tomoyo_same_mkdev_acl,
469 tomoyo_merge_mkdev_acl); 467 tomoyo_merge_mkdev_acl);
470 tomoyo_put_name_union(&e.name); 468 tomoyo_put_name_union(&e.name);
471 tomoyo_put_number_union(&e.mode); 469 tomoyo_put_number_union(&e.mode);
472 tomoyo_put_number_union(&e.major); 470 tomoyo_put_number_union(&e.major);
473 tomoyo_put_number_union(&e.minor); 471 tomoyo_put_number_union(&e.minor);
474 return error; 472 return error;
475 } 473 }
476 474
477 /** 475 /**
478 * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry. 476 * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
479 * 477 *
480 * @a: Pointer to "struct tomoyo_acl_info". 478 * @a: Pointer to "struct tomoyo_acl_info".
481 * @b: Pointer to "struct tomoyo_acl_info". 479 * @b: Pointer to "struct tomoyo_acl_info".
482 * 480 *
483 * Returns true if @a == @b except permission bits, false otherwise. 481 * Returns true if @a == @b except permission bits, false otherwise.
484 */ 482 */
485 static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a, 483 static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
486 const struct tomoyo_acl_info *b) 484 const struct tomoyo_acl_info *b)
487 { 485 {
488 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head); 486 const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
489 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head); 487 const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
490 return tomoyo_same_name_union(&p1->name1, &p2->name1) && 488 return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
491 tomoyo_same_name_union(&p1->name2, &p2->name2); 489 tomoyo_same_name_union(&p1->name2, &p2->name2);
492 } 490 }
493 491
494 /** 492 /**
495 * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry. 493 * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
496 * 494 *
497 * @a: Pointer to "struct tomoyo_acl_info". 495 * @a: Pointer to "struct tomoyo_acl_info".
498 * @b: Pointer to "struct tomoyo_acl_info". 496 * @b: Pointer to "struct tomoyo_acl_info".
499 * @is_delete: True for @a &= ~@b, false for @a |= @b. 497 * @is_delete: True for @a &= ~@b, false for @a |= @b.
500 * 498 *
501 * Returns true if @a is empty, false otherwise. 499 * Returns true if @a is empty, false otherwise.
502 */ 500 */
503 static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a, 501 static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
504 struct tomoyo_acl_info *b, 502 struct tomoyo_acl_info *b,
505 const bool is_delete) 503 const bool is_delete)
506 { 504 {
507 u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head) 505 u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head)
508 ->perm; 506 ->perm;
509 u8 perm = *a_perm; 507 u8 perm = *a_perm;
510 const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm; 508 const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm;
511 if (is_delete) 509 if (is_delete)
512 perm &= ~b_perm; 510 perm &= ~b_perm;
513 else 511 else
514 perm |= b_perm; 512 perm |= b_perm;
515 *a_perm = perm; 513 *a_perm = perm;
516 return !perm; 514 return !perm;
517 } 515 }
518 516
519 /** 517 /**
520 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list. 518 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
521 * 519 *
522 * @perm: Permission. 520 * @perm: Permission.
523 * @param: Pointer to "struct tomoyo_acl_param". 521 * @param: Pointer to "struct tomoyo_acl_param".
524 * 522 *
525 * Returns 0 on success, negative value otherwise. 523 * Returns 0 on success, negative value otherwise.
526 * 524 *
527 * Caller holds tomoyo_read_lock(). 525 * Caller holds tomoyo_read_lock().
528 */ 526 */
529 static int tomoyo_update_path2_acl(const u8 perm, 527 static int tomoyo_update_path2_acl(const u8 perm,
530 struct tomoyo_acl_param *param) 528 struct tomoyo_acl_param *param)
531 { 529 {
532 struct tomoyo_path2_acl e = { 530 struct tomoyo_path2_acl e = {
533 .head.type = TOMOYO_TYPE_PATH2_ACL, 531 .head.type = TOMOYO_TYPE_PATH2_ACL,
534 .perm = perm 532 .perm = perm
535 }; 533 };
536 int error; 534 int error;
537 if (!tomoyo_parse_name_union(param, &e.name1) || 535 if (!tomoyo_parse_name_union(param, &e.name1) ||
538 !tomoyo_parse_name_union(param, &e.name2)) 536 !tomoyo_parse_name_union(param, &e.name2))
539 error = -EINVAL; 537 error = -EINVAL;
540 else 538 else
541 error = tomoyo_update_domain(&e.head, sizeof(e), param, 539 error = tomoyo_update_domain(&e.head, sizeof(e), param,
542 tomoyo_same_path2_acl, 540 tomoyo_same_path2_acl,
543 tomoyo_merge_path2_acl); 541 tomoyo_merge_path2_acl);
544 tomoyo_put_name_union(&e.name1); 542 tomoyo_put_name_union(&e.name1);
545 tomoyo_put_name_union(&e.name2); 543 tomoyo_put_name_union(&e.name2);
546 return error; 544 return error;
547 } 545 }
548 546
549 /** 547 /**
550 * tomoyo_path_permission - Check permission for single path operation. 548 * tomoyo_path_permission - Check permission for single path operation.
551 * 549 *
552 * @r: Pointer to "struct tomoyo_request_info". 550 * @r: Pointer to "struct tomoyo_request_info".
553 * @operation: Type of operation. 551 * @operation: Type of operation.
554 * @filename: Filename to check. 552 * @filename: Filename to check.
555 * 553 *
556 * Returns 0 on success, negative value otherwise. 554 * Returns 0 on success, negative value otherwise.
557 * 555 *
558 * Caller holds tomoyo_read_lock(). 556 * Caller holds tomoyo_read_lock().
559 */ 557 */
560 int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 558 int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
561 const struct tomoyo_path_info *filename) 559 const struct tomoyo_path_info *filename)
562 { 560 {
563 int error; 561 int error;
564 562
565 r->type = tomoyo_p2mac[operation]; 563 r->type = tomoyo_p2mac[operation];
566 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type); 564 r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
567 if (r->mode == TOMOYO_CONFIG_DISABLED) 565 if (r->mode == TOMOYO_CONFIG_DISABLED)
568 return 0; 566 return 0;
569 r->param_type = TOMOYO_TYPE_PATH_ACL; 567 r->param_type = TOMOYO_TYPE_PATH_ACL;
570 r->param.path.filename = filename; 568 r->param.path.filename = filename;
571 r->param.path.operation = operation; 569 r->param.path.operation = operation;
572 do { 570 do {
573 tomoyo_check_acl(r, tomoyo_check_path_acl); 571 tomoyo_check_acl(r, tomoyo_check_path_acl);
574 error = tomoyo_audit_path_log(r); 572 error = tomoyo_audit_path_log(r);
575 /* 573 /*
576 * Do not retry for execute request, for alias may have 574 * Do not retry for execute request, for alias may have
577 * changed. 575 * changed.
578 */ 576 */
579 } while (error == TOMOYO_RETRY_REQUEST && 577 } while (error == TOMOYO_RETRY_REQUEST &&
580 operation != TOMOYO_TYPE_EXECUTE); 578 operation != TOMOYO_TYPE_EXECUTE);
581 return error; 579 return error;
582 } 580 }
583 581
584 /** 582 /**
585 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry. 583 * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
586 * 584 *
587 * @a: Pointer to "struct tomoyo_acl_info". 585 * @a: Pointer to "struct tomoyo_acl_info".
588 * @b: Pointer to "struct tomoyo_acl_info". 586 * @b: Pointer to "struct tomoyo_acl_info".
589 * 587 *
590 * Returns true if @a == @b except permission bits, false otherwise. 588 * Returns true if @a == @b except permission bits, false otherwise.
591 */ 589 */
592 static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 590 static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
593 const struct tomoyo_acl_info *b) 591 const struct tomoyo_acl_info *b)
594 { 592 {
595 const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1), 593 const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
596 head); 594 head);
597 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2), 595 const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
598 head); 596 head);
599 return tomoyo_same_name_union(&p1->name, &p2->name) && 597 return tomoyo_same_name_union(&p1->name, &p2->name) &&
600 tomoyo_same_number_union(&p1->number, &p2->number); 598 tomoyo_same_number_union(&p1->number, &p2->number);
601 } 599 }
602 600
603 /** 601 /**
604 * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry. 602 * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
605 * 603 *
606 * @a: Pointer to "struct tomoyo_acl_info". 604 * @a: Pointer to "struct tomoyo_acl_info".
607 * @b: Pointer to "struct tomoyo_acl_info". 605 * @b: Pointer to "struct tomoyo_acl_info".
608 * @is_delete: True for @a &= ~@b, false for @a |= @b. 606 * @is_delete: True for @a &= ~@b, false for @a |= @b.
609 * 607 *
610 * Returns true if @a is empty, false otherwise. 608 * Returns true if @a is empty, false otherwise.
611 */ 609 */
612 static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a, 610 static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
613 struct tomoyo_acl_info *b, 611 struct tomoyo_acl_info *b,
614 const bool is_delete) 612 const bool is_delete)
615 { 613 {
616 u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl, 614 u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
617 head)->perm; 615 head)->perm;
618 u8 perm = *a_perm; 616 u8 perm = *a_perm;
619 const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head) 617 const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
620 ->perm; 618 ->perm;
621 if (is_delete) 619 if (is_delete)
622 perm &= ~b_perm; 620 perm &= ~b_perm;
623 else 621 else
624 perm |= b_perm; 622 perm |= b_perm;
625 *a_perm = perm; 623 *a_perm = perm;
626 return !perm; 624 return !perm;
627 } 625 }
628 626
629 /** 627 /**
630 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL. 628 * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
631 * 629 *
632 * @perm: Permission. 630 * @perm: Permission.
633 * @param: Pointer to "struct tomoyo_acl_param". 631 * @param: Pointer to "struct tomoyo_acl_param".
634 * 632 *
635 * Returns 0 on success, negative value otherwise. 633 * Returns 0 on success, negative value otherwise.
636 */ 634 */
637 static int tomoyo_update_path_number_acl(const u8 perm, 635 static int tomoyo_update_path_number_acl(const u8 perm,
638 struct tomoyo_acl_param *param) 636 struct tomoyo_acl_param *param)
639 { 637 {
640 struct tomoyo_path_number_acl e = { 638 struct tomoyo_path_number_acl e = {
641 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL, 639 .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
642 .perm = perm 640 .perm = perm
643 }; 641 };
644 int error; 642 int error;
645 if (!tomoyo_parse_name_union(param, &e.name) || 643 if (!tomoyo_parse_name_union(param, &e.name) ||
646 !tomoyo_parse_number_union(param, &e.number)) 644 !tomoyo_parse_number_union(param, &e.number))
647 error = -EINVAL; 645 error = -EINVAL;
648 else 646 else
649 error = tomoyo_update_domain(&e.head, sizeof(e), param, 647 error = tomoyo_update_domain(&e.head, sizeof(e), param,
650 tomoyo_same_path_number_acl, 648 tomoyo_same_path_number_acl,
651 tomoyo_merge_path_number_acl); 649 tomoyo_merge_path_number_acl);
652 tomoyo_put_name_union(&e.name); 650 tomoyo_put_name_union(&e.name);
653 tomoyo_put_number_union(&e.number); 651 tomoyo_put_number_union(&e.number);
654 return error; 652 return error;
655 } 653 }
656 654
657 /** 655 /**
658 * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp". 656 * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
659 * 657 *
660 * @type: Type of operation. 658 * @type: Type of operation.
661 * @path: Pointer to "struct path". 659 * @path: Pointer to "struct path".
662 * @number: Number. 660 * @number: Number.
663 * 661 *
664 * Returns 0 on success, negative value otherwise. 662 * Returns 0 on success, negative value otherwise.
665 */ 663 */
666 int tomoyo_path_number_perm(const u8 type, struct path *path, 664 int tomoyo_path_number_perm(const u8 type, struct path *path,
667 unsigned long number) 665 unsigned long number)
668 { 666 {
669 struct tomoyo_request_info r; 667 struct tomoyo_request_info r;
670 struct tomoyo_obj_info obj = { 668 struct tomoyo_obj_info obj = {
671 .path1 = *path, 669 .path1 = *path,
672 }; 670 };
673 int error = -ENOMEM; 671 int error = -ENOMEM;
674 struct tomoyo_path_info buf; 672 struct tomoyo_path_info buf;
675 int idx; 673 int idx;
676 674
677 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type]) 675 if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
678 == TOMOYO_CONFIG_DISABLED || !path->dentry) 676 == TOMOYO_CONFIG_DISABLED || !path->dentry)
679 return 0; 677 return 0;
680 idx = tomoyo_read_lock(); 678 idx = tomoyo_read_lock();
681 if (!tomoyo_get_realpath(&buf, path)) 679 if (!tomoyo_get_realpath(&buf, path))
682 goto out; 680 goto out;
683 r.obj = &obj; 681 r.obj = &obj;
684 if (type == TOMOYO_TYPE_MKDIR) 682 if (type == TOMOYO_TYPE_MKDIR)
685 tomoyo_add_slash(&buf); 683 tomoyo_add_slash(&buf);
686 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; 684 r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
687 r.param.path_number.operation = type; 685 r.param.path_number.operation = type;
688 r.param.path_number.filename = &buf; 686 r.param.path_number.filename = &buf;
689 r.param.path_number.number = number; 687 r.param.path_number.number = number;
690 do { 688 do {
691 tomoyo_check_acl(&r, tomoyo_check_path_number_acl); 689 tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
692 error = tomoyo_audit_path_number_log(&r); 690 error = tomoyo_audit_path_number_log(&r);
693 } while (error == TOMOYO_RETRY_REQUEST); 691 } while (error == TOMOYO_RETRY_REQUEST);
694 kfree(buf.name); 692 kfree(buf.name);
695 out: 693 out:
696 tomoyo_read_unlock(idx); 694 tomoyo_read_unlock(idx);
697 if (r.mode != TOMOYO_CONFIG_ENFORCING) 695 if (r.mode != TOMOYO_CONFIG_ENFORCING)
698 error = 0; 696 error = 0;
699 return error; 697 return error;
700 } 698 }
701 699
702 /** 700 /**
703 * tomoyo_check_open_permission - Check permission for "read" and "write". 701 * tomoyo_check_open_permission - Check permission for "read" and "write".
704 * 702 *
705 * @domain: Pointer to "struct tomoyo_domain_info". 703 * @domain: Pointer to "struct tomoyo_domain_info".
706 * @path: Pointer to "struct path". 704 * @path: Pointer to "struct path".
707 * @flag: Flags for open(). 705 * @flag: Flags for open().
708 * 706 *
709 * Returns 0 on success, negative value otherwise. 707 * Returns 0 on success, negative value otherwise.
710 */ 708 */
711 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain, 709 int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
712 struct path *path, const int flag) 710 struct path *path, const int flag)
713 { 711 {
714 const u8 acc_mode = ACC_MODE(flag); 712 const u8 acc_mode = ACC_MODE(flag);
715 int error = 0; 713 int error = 0;
716 struct tomoyo_path_info buf; 714 struct tomoyo_path_info buf;
717 struct tomoyo_request_info r; 715 struct tomoyo_request_info r;
718 struct tomoyo_obj_info obj = { 716 struct tomoyo_obj_info obj = {
719 .path1 = *path, 717 .path1 = *path,
720 }; 718 };
721 int idx; 719 int idx;
722 720
723 buf.name = NULL; 721 buf.name = NULL;
724 r.mode = TOMOYO_CONFIG_DISABLED; 722 r.mode = TOMOYO_CONFIG_DISABLED;
725 idx = tomoyo_read_lock(); 723 idx = tomoyo_read_lock();
726 if (acc_mode && 724 if (acc_mode &&
727 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN) 725 tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
728 != TOMOYO_CONFIG_DISABLED) { 726 != TOMOYO_CONFIG_DISABLED) {
729 if (!tomoyo_get_realpath(&buf, path)) { 727 if (!tomoyo_get_realpath(&buf, path)) {
730 error = -ENOMEM; 728 error = -ENOMEM;
731 goto out; 729 goto out;
732 } 730 }
733 r.obj = &obj; 731 r.obj = &obj;
734 if (acc_mode & MAY_READ) 732 if (acc_mode & MAY_READ)
735 error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ, 733 error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
736 &buf); 734 &buf);
737 if (!error && (acc_mode & MAY_WRITE)) 735 if (!error && (acc_mode & MAY_WRITE))
738 error = tomoyo_path_permission(&r, (flag & O_APPEND) ? 736 error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
739 TOMOYO_TYPE_APPEND : 737 TOMOYO_TYPE_APPEND :
740 TOMOYO_TYPE_WRITE, 738 TOMOYO_TYPE_WRITE,
741 &buf); 739 &buf);
742 } 740 }
743 out: 741 out:
744 kfree(buf.name); 742 kfree(buf.name);
745 tomoyo_read_unlock(idx); 743 tomoyo_read_unlock(idx);
746 if (r.mode != TOMOYO_CONFIG_ENFORCING) 744 if (r.mode != TOMOYO_CONFIG_ENFORCING)
747 error = 0; 745 error = 0;
748 return error; 746 return error;
749 } 747 }
750 748
751 /** 749 /**
752 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount". 750 * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
753 * 751 *
754 * @operation: Type of operation. 752 * @operation: Type of operation.
755 * @path: Pointer to "struct path". 753 * @path: Pointer to "struct path".
756 * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK, 754 * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
757 * NULL otherwise. 755 * NULL otherwise.
758 * 756 *
759 * Returns 0 on success, negative value otherwise. 757 * Returns 0 on success, negative value otherwise.
760 */ 758 */
761 int tomoyo_path_perm(const u8 operation, struct path *path, const char *target) 759 int tomoyo_path_perm(const u8 operation, struct path *path, const char *target)
762 { 760 {
763 struct tomoyo_request_info r; 761 struct tomoyo_request_info r;
764 struct tomoyo_obj_info obj = { 762 struct tomoyo_obj_info obj = {
765 .path1 = *path, 763 .path1 = *path,
766 }; 764 };
767 int error; 765 int error;
768 struct tomoyo_path_info buf; 766 struct tomoyo_path_info buf;
769 bool is_enforce; 767 bool is_enforce;
770 struct tomoyo_path_info symlink_target; 768 struct tomoyo_path_info symlink_target;
771 int idx; 769 int idx;
772 770
773 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation]) 771 if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
774 == TOMOYO_CONFIG_DISABLED) 772 == TOMOYO_CONFIG_DISABLED)
775 return 0; 773 return 0;
776 is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING); 774 is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
777 error = -ENOMEM; 775 error = -ENOMEM;
778 buf.name = NULL; 776 buf.name = NULL;
779 idx = tomoyo_read_lock(); 777 idx = tomoyo_read_lock();
780 if (!tomoyo_get_realpath(&buf, path)) 778 if (!tomoyo_get_realpath(&buf, path))
781 goto out; 779 goto out;
782 r.obj = &obj; 780 r.obj = &obj;
783 switch (operation) { 781 switch (operation) {
784 case TOMOYO_TYPE_RMDIR: 782 case TOMOYO_TYPE_RMDIR:
785 case TOMOYO_TYPE_CHROOT: 783 case TOMOYO_TYPE_CHROOT:
786 tomoyo_add_slash(&buf); 784 tomoyo_add_slash(&buf);
787 break; 785 break;
788 case TOMOYO_TYPE_SYMLINK: 786 case TOMOYO_TYPE_SYMLINK:
789 symlink_target.name = tomoyo_encode(target); 787 symlink_target.name = tomoyo_encode(target);
790 if (!symlink_target.name) 788 if (!symlink_target.name)
791 goto out; 789 goto out;
792 tomoyo_fill_path_info(&symlink_target); 790 tomoyo_fill_path_info(&symlink_target);
793 obj.symlink_target = &symlink_target; 791 obj.symlink_target = &symlink_target;
794 break; 792 break;
795 } 793 }
796 error = tomoyo_path_permission(&r, operation, &buf); 794 error = tomoyo_path_permission(&r, operation, &buf);
797 if (operation == TOMOYO_TYPE_SYMLINK) 795 if (operation == TOMOYO_TYPE_SYMLINK)
798 kfree(symlink_target.name); 796 kfree(symlink_target.name);
799 out: 797 out:
800 kfree(buf.name); 798 kfree(buf.name);
801 tomoyo_read_unlock(idx); 799 tomoyo_read_unlock(idx);
802 if (!is_enforce) 800 if (!is_enforce)
803 error = 0; 801 error = 0;
804 return error; 802 return error;
805 } 803 }
806 804
807 /** 805 /**
808 * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar". 806 * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
809 * 807 *
810 * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK) 808 * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
811 * @path: Pointer to "struct path". 809 * @path: Pointer to "struct path".
812 * @mode: Create mode. 810 * @mode: Create mode.
813 * @dev: Device number. 811 * @dev: Device number.
814 * 812 *
815 * Returns 0 on success, negative value otherwise. 813 * Returns 0 on success, negative value otherwise.
816 */ 814 */
817 int tomoyo_mkdev_perm(const u8 operation, struct path *path, 815 int tomoyo_mkdev_perm(const u8 operation, struct path *path,
818 const unsigned int mode, unsigned int dev) 816 const unsigned int mode, unsigned int dev)
819 { 817 {
820 struct tomoyo_request_info r; 818 struct tomoyo_request_info r;
821 struct tomoyo_obj_info obj = { 819 struct tomoyo_obj_info obj = {
822 .path1 = *path, 820 .path1 = *path,
823 }; 821 };
824 int error = -ENOMEM; 822 int error = -ENOMEM;
825 struct tomoyo_path_info buf; 823 struct tomoyo_path_info buf;
826 int idx; 824 int idx;
827 825
828 if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation]) 826 if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
829 == TOMOYO_CONFIG_DISABLED) 827 == TOMOYO_CONFIG_DISABLED)
830 return 0; 828 return 0;
831 idx = tomoyo_read_lock(); 829 idx = tomoyo_read_lock();
832 error = -ENOMEM; 830 error = -ENOMEM;
833 if (tomoyo_get_realpath(&buf, path)) { 831 if (tomoyo_get_realpath(&buf, path)) {
834 r.obj = &obj; 832 r.obj = &obj;
835 dev = new_decode_dev(dev); 833 dev = new_decode_dev(dev);
836 r.param_type = TOMOYO_TYPE_MKDEV_ACL; 834 r.param_type = TOMOYO_TYPE_MKDEV_ACL;
837 r.param.mkdev.filename = &buf; 835 r.param.mkdev.filename = &buf;
838 r.param.mkdev.operation = operation; 836 r.param.mkdev.operation = operation;
839 r.param.mkdev.mode = mode; 837 r.param.mkdev.mode = mode;
840 r.param.mkdev.major = MAJOR(dev); 838 r.param.mkdev.major = MAJOR(dev);
841 r.param.mkdev.minor = MINOR(dev); 839 r.param.mkdev.minor = MINOR(dev);
842 tomoyo_check_acl(&r, tomoyo_check_mkdev_acl); 840 tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
843 error = tomoyo_audit_mkdev_log(&r); 841 error = tomoyo_audit_mkdev_log(&r);
844 kfree(buf.name); 842 kfree(buf.name);
845 } 843 }
846 tomoyo_read_unlock(idx); 844 tomoyo_read_unlock(idx);
847 if (r.mode != TOMOYO_CONFIG_ENFORCING) 845 if (r.mode != TOMOYO_CONFIG_ENFORCING)
848 error = 0; 846 error = 0;
849 return error; 847 return error;
850 } 848 }
851 849
852 /** 850 /**
853 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root". 851 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
854 * 852 *
855 * @operation: Type of operation. 853 * @operation: Type of operation.
856 * @path1: Pointer to "struct path". 854 * @path1: Pointer to "struct path".
857 * @path2: Pointer to "struct path". 855 * @path2: Pointer to "struct path".
858 * 856 *
859 * Returns 0 on success, negative value otherwise. 857 * Returns 0 on success, negative value otherwise.
860 */ 858 */
861 int tomoyo_path2_perm(const u8 operation, struct path *path1, 859 int tomoyo_path2_perm(const u8 operation, struct path *path1,
862 struct path *path2) 860 struct path *path2)
863 { 861 {
864 int error = -ENOMEM; 862 int error = -ENOMEM;
865 struct tomoyo_path_info buf1; 863 struct tomoyo_path_info buf1;
866 struct tomoyo_path_info buf2; 864 struct tomoyo_path_info buf2;
867 struct tomoyo_request_info r; 865 struct tomoyo_request_info r;
868 struct tomoyo_obj_info obj = { 866 struct tomoyo_obj_info obj = {
869 .path1 = *path1, 867 .path1 = *path1,
870 .path2 = *path2, 868 .path2 = *path2,
871 }; 869 };
872 int idx; 870 int idx;
873 871
874 if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation]) 872 if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
875 == TOMOYO_CONFIG_DISABLED) 873 == TOMOYO_CONFIG_DISABLED)
876 return 0; 874 return 0;
877 buf1.name = NULL; 875 buf1.name = NULL;
878 buf2.name = NULL; 876 buf2.name = NULL;
879 idx = tomoyo_read_lock(); 877 idx = tomoyo_read_lock();
880 if (!tomoyo_get_realpath(&buf1, path1) || 878 if (!tomoyo_get_realpath(&buf1, path1) ||
881 !tomoyo_get_realpath(&buf2, path2)) 879 !tomoyo_get_realpath(&buf2, path2))
882 goto out; 880 goto out;
883 switch (operation) { 881 switch (operation) {
884 struct dentry *dentry; 882 struct dentry *dentry;
885 case TOMOYO_TYPE_RENAME: 883 case TOMOYO_TYPE_RENAME:
886 case TOMOYO_TYPE_LINK: 884 case TOMOYO_TYPE_LINK:
887 dentry = path1->dentry; 885 dentry = path1->dentry;
888 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) 886 if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode))
889 break; 887 break;
890 /* fall through */ 888 /* fall through */
891 case TOMOYO_TYPE_PIVOT_ROOT: 889 case TOMOYO_TYPE_PIVOT_ROOT:
892 tomoyo_add_slash(&buf1); 890 tomoyo_add_slash(&buf1);
893 tomoyo_add_slash(&buf2); 891 tomoyo_add_slash(&buf2);
894 break; 892 break;
895 } 893 }
896 r.obj = &obj; 894 r.obj = &obj;
897 r.param_type = TOMOYO_TYPE_PATH2_ACL; 895 r.param_type = TOMOYO_TYPE_PATH2_ACL;
898 r.param.path2.operation = operation; 896 r.param.path2.operation = operation;
899 r.param.path2.filename1 = &buf1; 897 r.param.path2.filename1 = &buf1;
900 r.param.path2.filename2 = &buf2; 898 r.param.path2.filename2 = &buf2;
901 do { 899 do {
902 tomoyo_check_acl(&r, tomoyo_check_path2_acl); 900 tomoyo_check_acl(&r, tomoyo_check_path2_acl);
903 error = tomoyo_audit_path2_log(&r); 901 error = tomoyo_audit_path2_log(&r);
904 } while (error == TOMOYO_RETRY_REQUEST); 902 } while (error == TOMOYO_RETRY_REQUEST);
905 out: 903 out:
906 kfree(buf1.name); 904 kfree(buf1.name);
907 kfree(buf2.name); 905 kfree(buf2.name);
908 tomoyo_read_unlock(idx); 906 tomoyo_read_unlock(idx);
909 if (r.mode != TOMOYO_CONFIG_ENFORCING) 907 if (r.mode != TOMOYO_CONFIG_ENFORCING)
910 error = 0; 908 error = 0;
911 return error; 909 return error;
912 } 910 }
913 911
914 /** 912 /**
915 * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry. 913 * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
916 * 914 *
917 * @a: Pointer to "struct tomoyo_acl_info". 915 * @a: Pointer to "struct tomoyo_acl_info".
918 * @b: Pointer to "struct tomoyo_acl_info". 916 * @b: Pointer to "struct tomoyo_acl_info".
919 * 917 *
920 * Returns true if @a == @b, false otherwise. 918 * Returns true if @a == @b, false otherwise.
921 */ 919 */
922 static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a, 920 static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
923 const struct tomoyo_acl_info *b) 921 const struct tomoyo_acl_info *b)
924 { 922 {
925 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head); 923 const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
926 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head); 924 const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
927 return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) && 925 return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
928 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) && 926 tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
929 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) && 927 tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
930 tomoyo_same_number_union(&p1->flags, &p2->flags); 928 tomoyo_same_number_union(&p1->flags, &p2->flags);
931 } 929 }
932 930
933 /** 931 /**
934 * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list. 932 * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
935 * 933 *
936 * @param: Pointer to "struct tomoyo_acl_param". 934 * @param: Pointer to "struct tomoyo_acl_param".
937 * 935 *
938 * Returns 0 on success, negative value otherwise. 936 * Returns 0 on success, negative value otherwise.
939 * 937 *
940 * Caller holds tomoyo_read_lock(). 938 * Caller holds tomoyo_read_lock().
941 */ 939 */
942 static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param) 940 static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
943 { 941 {
944 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL }; 942 struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
945 int error; 943 int error;
946 if (!tomoyo_parse_name_union(param, &e.dev_name) || 944 if (!tomoyo_parse_name_union(param, &e.dev_name) ||
947 !tomoyo_parse_name_union(param, &e.dir_name) || 945 !tomoyo_parse_name_union(param, &e.dir_name) ||
948 !tomoyo_parse_name_union(param, &e.fs_type) || 946 !tomoyo_parse_name_union(param, &e.fs_type) ||
949 !tomoyo_parse_number_union(param, &e.flags)) 947 !tomoyo_parse_number_union(param, &e.flags))
950 error = -EINVAL; 948 error = -EINVAL;
951 else 949 else
952 error = tomoyo_update_domain(&e.head, sizeof(e), param, 950 error = tomoyo_update_domain(&e.head, sizeof(e), param,
953 tomoyo_same_mount_acl, NULL); 951 tomoyo_same_mount_acl, NULL);
954 tomoyo_put_name_union(&e.dev_name); 952 tomoyo_put_name_union(&e.dev_name);
955 tomoyo_put_name_union(&e.dir_name); 953 tomoyo_put_name_union(&e.dir_name);
956 tomoyo_put_name_union(&e.fs_type); 954 tomoyo_put_name_union(&e.fs_type);
957 tomoyo_put_number_union(&e.flags); 955 tomoyo_put_number_union(&e.flags);
958 return error; 956 return error;
959 } 957 }
960 958
961 /** 959 /**
962 * tomoyo_write_file - Update file related list. 960 * tomoyo_write_file - Update file related list.
963 * 961 *
964 * @param: Pointer to "struct tomoyo_acl_param". 962 * @param: Pointer to "struct tomoyo_acl_param".
965 * 963 *
966 * Returns 0 on success, negative value otherwise. 964 * Returns 0 on success, negative value otherwise.
967 * 965 *
968 * Caller holds tomoyo_read_lock(). 966 * Caller holds tomoyo_read_lock().
969 */ 967 */
970 int tomoyo_write_file(struct tomoyo_acl_param *param) 968 int tomoyo_write_file(struct tomoyo_acl_param *param)
971 { 969 {
972 u16 perm = 0; 970 u16 perm = 0;
973 u8 type; 971 u8 type;
974 const char *operation = tomoyo_read_token(param); 972 const char *operation = tomoyo_read_token(param);
975 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) 973 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
976 if (tomoyo_permstr(operation, tomoyo_path_keyword[type])) 974 if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
977 perm |= 1 << type; 975 perm |= 1 << type;
978 if (perm) 976 if (perm)
979 return tomoyo_update_path_acl(perm, param); 977 return tomoyo_update_path_acl(perm, param);
980 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) 978 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
981 if (tomoyo_permstr(operation, 979 if (tomoyo_permstr(operation,
982 tomoyo_mac_keywords[tomoyo_pp2mac[type]])) 980 tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
983 perm |= 1 << type; 981 perm |= 1 << type;
984 if (perm) 982 if (perm)
985 return tomoyo_update_path2_acl(perm, param); 983 return tomoyo_update_path2_acl(perm, param);
986 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++) 984 for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
987 if (tomoyo_permstr(operation, 985 if (tomoyo_permstr(operation,
988 tomoyo_mac_keywords[tomoyo_pn2mac[type]])) 986 tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
989 perm |= 1 << type; 987 perm |= 1 << type;
990 if (perm) 988 if (perm)
991 return tomoyo_update_path_number_acl(perm, param); 989 return tomoyo_update_path_number_acl(perm, param);
992 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++) 990 for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
993 if (tomoyo_permstr(operation, 991 if (tomoyo_permstr(operation,
994 tomoyo_mac_keywords[tomoyo_pnnn2mac[type]])) 992 tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
995 perm |= 1 << type; 993 perm |= 1 << type;
996 if (perm) 994 if (perm)
997 return tomoyo_update_mkdev_acl(perm, param); 995 return tomoyo_update_mkdev_acl(perm, param);
998 if (tomoyo_permstr(operation, 996 if (tomoyo_permstr(operation,
999 tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT])) 997 tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
1000 return tomoyo_update_mount_acl(param); 998 return tomoyo_update_mount_acl(param);
1001 return -EINVAL; 999 return -EINVAL;
1002 } 1000 }
1003 1001
security/tomoyo/gc.c
1 /* 1 /*
2 * security/tomoyo/gc.c 2 * security/tomoyo/gc.c
3 * 3 *
4 * Implementation of the Domain-Based Mandatory Access Control. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 *
8 */ 5 */
9 6
10 #include "common.h" 7 #include "common.h"
11 #include <linux/kthread.h> 8 #include <linux/kthread.h>
12 #include <linux/slab.h> 9 #include <linux/slab.h>
13 10
14 /* The list for "struct tomoyo_io_buffer". */ 11 /* The list for "struct tomoyo_io_buffer". */
15 static LIST_HEAD(tomoyo_io_buffer_list); 12 static LIST_HEAD(tomoyo_io_buffer_list);
16 /* Lock for protecting tomoyo_io_buffer_list. */ 13 /* Lock for protecting tomoyo_io_buffer_list. */
17 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock); 14 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
18 15
19 /* Size of an element. */ 16 /* Size of an element. */
20 static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = { 17 static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
21 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group), 18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
22 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group), 19 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
23 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group), 20 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
24 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator), 21 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
25 [TOMOYO_ID_TRANSITION_CONTROL] = 22 [TOMOYO_ID_TRANSITION_CONTROL] =
26 sizeof(struct tomoyo_transition_control), 23 sizeof(struct tomoyo_transition_control),
27 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager), 24 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
28 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */ 25 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
29 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */ 26 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
30 /* [TOMOYO_ID_ACL] = 27 /* [TOMOYO_ID_ACL] =
31 tomoyo_acl_size["struct tomoyo_acl_info"->type], */ 28 tomoyo_acl_size["struct tomoyo_acl_info"->type], */
32 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info), 29 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
33 }; 30 };
34 31
35 /* Size of a domain ACL element. */ 32 /* Size of a domain ACL element. */
36 static const u8 tomoyo_acl_size[] = { 33 static const u8 tomoyo_acl_size[] = {
37 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl), 34 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
38 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl), 35 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
39 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl), 36 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
40 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl), 37 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
41 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl), 38 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
42 }; 39 };
43 40
44 /** 41 /**
45 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not. 42 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
46 * 43 *
47 * @element: Pointer to "struct list_head". 44 * @element: Pointer to "struct list_head".
48 * 45 *
49 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users, 46 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
50 * false otherwise. 47 * false otherwise.
51 */ 48 */
52 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element) 49 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
53 { 50 {
54 struct tomoyo_io_buffer *head; 51 struct tomoyo_io_buffer *head;
55 bool in_use = false; 52 bool in_use = false;
56 53
57 spin_lock(&tomoyo_io_buffer_list_lock); 54 spin_lock(&tomoyo_io_buffer_list_lock);
58 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 55 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
59 head->users++; 56 head->users++;
60 spin_unlock(&tomoyo_io_buffer_list_lock); 57 spin_unlock(&tomoyo_io_buffer_list_lock);
61 if (mutex_lock_interruptible(&head->io_sem)) { 58 if (mutex_lock_interruptible(&head->io_sem)) {
62 in_use = true; 59 in_use = true;
63 goto out; 60 goto out;
64 } 61 }
65 if (head->r.domain == element || head->r.group == element || 62 if (head->r.domain == element || head->r.group == element ||
66 head->r.acl == element || &head->w.domain->list == element) 63 head->r.acl == element || &head->w.domain->list == element)
67 in_use = true; 64 in_use = true;
68 mutex_unlock(&head->io_sem); 65 mutex_unlock(&head->io_sem);
69 out: 66 out:
70 spin_lock(&tomoyo_io_buffer_list_lock); 67 spin_lock(&tomoyo_io_buffer_list_lock);
71 head->users--; 68 head->users--;
72 if (in_use) 69 if (in_use)
73 break; 70 break;
74 } 71 }
75 spin_unlock(&tomoyo_io_buffer_list_lock); 72 spin_unlock(&tomoyo_io_buffer_list_lock);
76 return in_use; 73 return in_use;
77 } 74 }
78 75
79 /** 76 /**
80 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not. 77 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
81 * 78 *
82 * @string: String to check. 79 * @string: String to check.
83 * @size: Memory allocated for @string . 80 * @size: Memory allocated for @string .
84 * 81 *
85 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users, 82 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
86 * false otherwise. 83 * false otherwise.
87 */ 84 */
88 static bool tomoyo_name_used_by_io_buffer(const char *string, 85 static bool tomoyo_name_used_by_io_buffer(const char *string,
89 const size_t size) 86 const size_t size)
90 { 87 {
91 struct tomoyo_io_buffer *head; 88 struct tomoyo_io_buffer *head;
92 bool in_use = false; 89 bool in_use = false;
93 90
94 spin_lock(&tomoyo_io_buffer_list_lock); 91 spin_lock(&tomoyo_io_buffer_list_lock);
95 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 92 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
96 int i; 93 int i;
97 head->users++; 94 head->users++;
98 spin_unlock(&tomoyo_io_buffer_list_lock); 95 spin_unlock(&tomoyo_io_buffer_list_lock);
99 if (mutex_lock_interruptible(&head->io_sem)) { 96 if (mutex_lock_interruptible(&head->io_sem)) {
100 in_use = true; 97 in_use = true;
101 goto out; 98 goto out;
102 } 99 }
103 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) { 100 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
104 const char *w = head->r.w[i]; 101 const char *w = head->r.w[i];
105 if (w < string || w > string + size) 102 if (w < string || w > string + size)
106 continue; 103 continue;
107 in_use = true; 104 in_use = true;
108 break; 105 break;
109 } 106 }
110 mutex_unlock(&head->io_sem); 107 mutex_unlock(&head->io_sem);
111 out: 108 out:
112 spin_lock(&tomoyo_io_buffer_list_lock); 109 spin_lock(&tomoyo_io_buffer_list_lock);
113 head->users--; 110 head->users--;
114 if (in_use) 111 if (in_use)
115 break; 112 break;
116 } 113 }
117 spin_unlock(&tomoyo_io_buffer_list_lock); 114 spin_unlock(&tomoyo_io_buffer_list_lock);
118 return in_use; 115 return in_use;
119 } 116 }
120 117
121 /* Structure for garbage collection. */ 118 /* Structure for garbage collection. */
122 struct tomoyo_gc { 119 struct tomoyo_gc {
123 struct list_head list; 120 struct list_head list;
124 enum tomoyo_policy_id type; 121 enum tomoyo_policy_id type;
125 size_t size; 122 size_t size;
126 struct list_head *element; 123 struct list_head *element;
127 }; 124 };
128 /* List of entries to be deleted. */ 125 /* List of entries to be deleted. */
129 static LIST_HEAD(tomoyo_gc_list); 126 static LIST_HEAD(tomoyo_gc_list);
130 /* Length of tomoyo_gc_list. */ 127 /* Length of tomoyo_gc_list. */
131 static int tomoyo_gc_list_len; 128 static int tomoyo_gc_list_len;
132 129
133 /** 130 /**
134 * tomoyo_add_to_gc - Add an entry to to be deleted list. 131 * tomoyo_add_to_gc - Add an entry to to be deleted list.
135 * 132 *
136 * @type: One of values in "enum tomoyo_policy_id". 133 * @type: One of values in "enum tomoyo_policy_id".
137 * @element: Pointer to "struct list_head". 134 * @element: Pointer to "struct list_head".
138 * 135 *
139 * Returns true on success, false otherwise. 136 * Returns true on success, false otherwise.
140 * 137 *
141 * Caller holds tomoyo_policy_lock mutex. 138 * Caller holds tomoyo_policy_lock mutex.
142 * 139 *
143 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of 140 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
144 * entries at once, it will take too long time. Thus, do not add more than 128 141 * entries at once, it will take too long time. Thus, do not add more than 128
145 * entries per a scan. But to be able to handle worst case where all entries 142 * entries per a scan. But to be able to handle worst case where all entries
146 * are in-use, we accept one more entry per a scan. 143 * are in-use, we accept one more entry per a scan.
147 * 144 *
148 * If we use singly linked list using "struct list_head"->prev (which is 145 * If we use singly linked list using "struct list_head"->prev (which is
149 * LIST_POISON2), we can avoid kmalloc(). 146 * LIST_POISON2), we can avoid kmalloc().
150 */ 147 */
151 static bool tomoyo_add_to_gc(const int type, struct list_head *element) 148 static bool tomoyo_add_to_gc(const int type, struct list_head *element)
152 { 149 {
153 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 150 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
154 if (!entry) 151 if (!entry)
155 return false; 152 return false;
156 entry->type = type; 153 entry->type = type;
157 if (type == TOMOYO_ID_ACL) 154 if (type == TOMOYO_ID_ACL)
158 entry->size = tomoyo_acl_size[ 155 entry->size = tomoyo_acl_size[
159 container_of(element, 156 container_of(element,
160 typeof(struct tomoyo_acl_info), 157 typeof(struct tomoyo_acl_info),
161 list)->type]; 158 list)->type];
162 else if (type == TOMOYO_ID_NAME) 159 else if (type == TOMOYO_ID_NAME)
163 entry->size = strlen(container_of(element, 160 entry->size = strlen(container_of(element,
164 typeof(struct tomoyo_name), 161 typeof(struct tomoyo_name),
165 head.list)->entry.name) + 1; 162 head.list)->entry.name) + 1;
166 else if (type == TOMOYO_ID_CONDITION) 163 else if (type == TOMOYO_ID_CONDITION)
167 entry->size = 164 entry->size =
168 container_of(element, typeof(struct tomoyo_condition), 165 container_of(element, typeof(struct tomoyo_condition),
169 head.list)->size; 166 head.list)->size;
170 else 167 else
171 entry->size = tomoyo_element_size[type]; 168 entry->size = tomoyo_element_size[type];
172 entry->element = element; 169 entry->element = element;
173 list_add(&entry->list, &tomoyo_gc_list); 170 list_add(&entry->list, &tomoyo_gc_list);
174 list_del_rcu(element); 171 list_del_rcu(element);
175 return tomoyo_gc_list_len++ < 128; 172 return tomoyo_gc_list_len++ < 128;
176 } 173 }
177 174
178 /** 175 /**
179 * tomoyo_element_linked_by_gc - Validate next element of an entry. 176 * tomoyo_element_linked_by_gc - Validate next element of an entry.
180 * 177 *
181 * @element: Pointer to an element. 178 * @element: Pointer to an element.
182 * @size: Size of @element in byte. 179 * @size: Size of @element in byte.
183 * 180 *
184 * Returns true if @element is linked by other elements in the garbage 181 * Returns true if @element is linked by other elements in the garbage
185 * collector's queue, false otherwise. 182 * collector's queue, false otherwise.
186 */ 183 */
187 static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size) 184 static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
188 { 185 {
189 struct tomoyo_gc *p; 186 struct tomoyo_gc *p;
190 list_for_each_entry(p, &tomoyo_gc_list, list) { 187 list_for_each_entry(p, &tomoyo_gc_list, list) {
191 const u8 *ptr = (const u8 *) p->element->next; 188 const u8 *ptr = (const u8 *) p->element->next;
192 if (ptr < element || element + size < ptr) 189 if (ptr < element || element + size < ptr)
193 continue; 190 continue;
194 return true; 191 return true;
195 } 192 }
196 return false; 193 return false;
197 } 194 }
198 195
199 /** 196 /**
200 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control". 197 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
201 * 198 *
202 * @element: Pointer to "struct list_head". 199 * @element: Pointer to "struct list_head".
203 * 200 *
204 * Returns nothing. 201 * Returns nothing.
205 */ 202 */
206 static void tomoyo_del_transition_control(struct list_head *element) 203 static void tomoyo_del_transition_control(struct list_head *element)
207 { 204 {
208 struct tomoyo_transition_control *ptr = 205 struct tomoyo_transition_control *ptr =
209 container_of(element, typeof(*ptr), head.list); 206 container_of(element, typeof(*ptr), head.list);
210 tomoyo_put_name(ptr->domainname); 207 tomoyo_put_name(ptr->domainname);
211 tomoyo_put_name(ptr->program); 208 tomoyo_put_name(ptr->program);
212 } 209 }
213 210
214 /** 211 /**
215 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator". 212 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
216 * 213 *
217 * @element: Pointer to "struct list_head". 214 * @element: Pointer to "struct list_head".
218 * 215 *
219 * Returns nothing. 216 * Returns nothing.
220 */ 217 */
221 static void tomoyo_del_aggregator(struct list_head *element) 218 static void tomoyo_del_aggregator(struct list_head *element)
222 { 219 {
223 struct tomoyo_aggregator *ptr = 220 struct tomoyo_aggregator *ptr =
224 container_of(element, typeof(*ptr), head.list); 221 container_of(element, typeof(*ptr), head.list);
225 tomoyo_put_name(ptr->original_name); 222 tomoyo_put_name(ptr->original_name);
226 tomoyo_put_name(ptr->aggregated_name); 223 tomoyo_put_name(ptr->aggregated_name);
227 } 224 }
228 225
229 /** 226 /**
230 * tomoyo_del_manager - Delete members in "struct tomoyo_manager". 227 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
231 * 228 *
232 * @element: Pointer to "struct list_head". 229 * @element: Pointer to "struct list_head".
233 * 230 *
234 * Returns nothing. 231 * Returns nothing.
235 */ 232 */
236 static void tomoyo_del_manager(struct list_head *element) 233 static void tomoyo_del_manager(struct list_head *element)
237 { 234 {
238 struct tomoyo_manager *ptr = 235 struct tomoyo_manager *ptr =
239 container_of(element, typeof(*ptr), head.list); 236 container_of(element, typeof(*ptr), head.list);
240 tomoyo_put_name(ptr->manager); 237 tomoyo_put_name(ptr->manager);
241 } 238 }
242 239
243 /** 240 /**
244 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info". 241 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
245 * 242 *
246 * @element: Pointer to "struct list_head". 243 * @element: Pointer to "struct list_head".
247 * 244 *
248 * Returns nothing. 245 * Returns nothing.
249 */ 246 */
250 static void tomoyo_del_acl(struct list_head *element) 247 static void tomoyo_del_acl(struct list_head *element)
251 { 248 {
252 struct tomoyo_acl_info *acl = 249 struct tomoyo_acl_info *acl =
253 container_of(element, typeof(*acl), list); 250 container_of(element, typeof(*acl), list);
254 tomoyo_put_condition(acl->cond); 251 tomoyo_put_condition(acl->cond);
255 switch (acl->type) { 252 switch (acl->type) {
256 case TOMOYO_TYPE_PATH_ACL: 253 case TOMOYO_TYPE_PATH_ACL:
257 { 254 {
258 struct tomoyo_path_acl *entry 255 struct tomoyo_path_acl *entry
259 = container_of(acl, typeof(*entry), head); 256 = container_of(acl, typeof(*entry), head);
260 tomoyo_put_name_union(&entry->name); 257 tomoyo_put_name_union(&entry->name);
261 } 258 }
262 break; 259 break;
263 case TOMOYO_TYPE_PATH2_ACL: 260 case TOMOYO_TYPE_PATH2_ACL:
264 { 261 {
265 struct tomoyo_path2_acl *entry 262 struct tomoyo_path2_acl *entry
266 = container_of(acl, typeof(*entry), head); 263 = container_of(acl, typeof(*entry), head);
267 tomoyo_put_name_union(&entry->name1); 264 tomoyo_put_name_union(&entry->name1);
268 tomoyo_put_name_union(&entry->name2); 265 tomoyo_put_name_union(&entry->name2);
269 } 266 }
270 break; 267 break;
271 case TOMOYO_TYPE_PATH_NUMBER_ACL: 268 case TOMOYO_TYPE_PATH_NUMBER_ACL:
272 { 269 {
273 struct tomoyo_path_number_acl *entry 270 struct tomoyo_path_number_acl *entry
274 = container_of(acl, typeof(*entry), head); 271 = container_of(acl, typeof(*entry), head);
275 tomoyo_put_name_union(&entry->name); 272 tomoyo_put_name_union(&entry->name);
276 tomoyo_put_number_union(&entry->number); 273 tomoyo_put_number_union(&entry->number);
277 } 274 }
278 break; 275 break;
279 case TOMOYO_TYPE_MKDEV_ACL: 276 case TOMOYO_TYPE_MKDEV_ACL:
280 { 277 {
281 struct tomoyo_mkdev_acl *entry 278 struct tomoyo_mkdev_acl *entry
282 = container_of(acl, typeof(*entry), head); 279 = container_of(acl, typeof(*entry), head);
283 tomoyo_put_name_union(&entry->name); 280 tomoyo_put_name_union(&entry->name);
284 tomoyo_put_number_union(&entry->mode); 281 tomoyo_put_number_union(&entry->mode);
285 tomoyo_put_number_union(&entry->major); 282 tomoyo_put_number_union(&entry->major);
286 tomoyo_put_number_union(&entry->minor); 283 tomoyo_put_number_union(&entry->minor);
287 } 284 }
288 break; 285 break;
289 case TOMOYO_TYPE_MOUNT_ACL: 286 case TOMOYO_TYPE_MOUNT_ACL:
290 { 287 {
291 struct tomoyo_mount_acl *entry 288 struct tomoyo_mount_acl *entry
292 = container_of(acl, typeof(*entry), head); 289 = container_of(acl, typeof(*entry), head);
293 tomoyo_put_name_union(&entry->dev_name); 290 tomoyo_put_name_union(&entry->dev_name);
294 tomoyo_put_name_union(&entry->dir_name); 291 tomoyo_put_name_union(&entry->dir_name);
295 tomoyo_put_name_union(&entry->fs_type); 292 tomoyo_put_name_union(&entry->fs_type);
296 tomoyo_put_number_union(&entry->flags); 293 tomoyo_put_number_union(&entry->flags);
297 } 294 }
298 break; 295 break;
299 } 296 }
300 } 297 }
301 298
302 /** 299 /**
303 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info". 300 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
304 * 301 *
305 * @element: Pointer to "struct list_head". 302 * @element: Pointer to "struct list_head".
306 * 303 *
307 * Returns true if deleted, false otherwise. 304 * Returns true if deleted, false otherwise.
308 */ 305 */
309 static bool tomoyo_del_domain(struct list_head *element) 306 static bool tomoyo_del_domain(struct list_head *element)
310 { 307 {
311 struct tomoyo_domain_info *domain = 308 struct tomoyo_domain_info *domain =
312 container_of(element, typeof(*domain), list); 309 container_of(element, typeof(*domain), list);
313 struct tomoyo_acl_info *acl; 310 struct tomoyo_acl_info *acl;
314 struct tomoyo_acl_info *tmp; 311 struct tomoyo_acl_info *tmp;
315 /* 312 /*
316 * Since we don't protect whole execve() operation using SRCU, 313 * Since we don't protect whole execve() operation using SRCU,
317 * we need to recheck domain->users at this point. 314 * we need to recheck domain->users at this point.
318 * 315 *
319 * (1) Reader starts SRCU section upon execve(). 316 * (1) Reader starts SRCU section upon execve().
320 * (2) Reader traverses tomoyo_domain_list and finds this domain. 317 * (2) Reader traverses tomoyo_domain_list and finds this domain.
321 * (3) Writer marks this domain as deleted. 318 * (3) Writer marks this domain as deleted.
322 * (4) Garbage collector removes this domain from tomoyo_domain_list 319 * (4) Garbage collector removes this domain from tomoyo_domain_list
323 * because this domain is marked as deleted and used by nobody. 320 * because this domain is marked as deleted and used by nobody.
324 * (5) Reader saves reference to this domain into 321 * (5) Reader saves reference to this domain into
325 * "struct linux_binprm"->cred->security . 322 * "struct linux_binprm"->cred->security .
326 * (6) Reader finishes SRCU section, although execve() operation has 323 * (6) Reader finishes SRCU section, although execve() operation has
327 * not finished yet. 324 * not finished yet.
328 * (7) Garbage collector waits for SRCU synchronization. 325 * (7) Garbage collector waits for SRCU synchronization.
329 * (8) Garbage collector kfree() this domain because this domain is 326 * (8) Garbage collector kfree() this domain because this domain is
330 * used by nobody. 327 * used by nobody.
331 * (9) Reader finishes execve() operation and restores this domain from 328 * (9) Reader finishes execve() operation and restores this domain from
332 * "struct linux_binprm"->cred->security. 329 * "struct linux_binprm"->cred->security.
333 * 330 *
334 * By updating domain->users at (5), we can solve this race problem 331 * By updating domain->users at (5), we can solve this race problem
335 * by rechecking domain->users at (8). 332 * by rechecking domain->users at (8).
336 */ 333 */
337 if (atomic_read(&domain->users)) 334 if (atomic_read(&domain->users))
338 return false; 335 return false;
339 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 336 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
340 tomoyo_del_acl(&acl->list); 337 tomoyo_del_acl(&acl->list);
341 tomoyo_memory_free(acl); 338 tomoyo_memory_free(acl);
342 } 339 }
343 tomoyo_put_name(domain->domainname); 340 tomoyo_put_name(domain->domainname);
344 return true; 341 return true;
345 } 342 }
346 343
347 /** 344 /**
348 * tomoyo_del_condition - Delete members in "struct tomoyo_condition". 345 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
349 * 346 *
350 * @element: Pointer to "struct list_head". 347 * @element: Pointer to "struct list_head".
351 * 348 *
352 * Returns nothing. 349 * Returns nothing.
353 */ 350 */
354 void tomoyo_del_condition(struct list_head *element) 351 void tomoyo_del_condition(struct list_head *element)
355 { 352 {
356 struct tomoyo_condition *cond = container_of(element, typeof(*cond), 353 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
357 head.list); 354 head.list);
358 const u16 condc = cond->condc; 355 const u16 condc = cond->condc;
359 const u16 numbers_count = cond->numbers_count; 356 const u16 numbers_count = cond->numbers_count;
360 const u16 names_count = cond->names_count; 357 const u16 names_count = cond->names_count;
361 const u16 argc = cond->argc; 358 const u16 argc = cond->argc;
362 const u16 envc = cond->envc; 359 const u16 envc = cond->envc;
363 unsigned int i; 360 unsigned int i;
364 const struct tomoyo_condition_element *condp 361 const struct tomoyo_condition_element *condp
365 = (const struct tomoyo_condition_element *) (cond + 1); 362 = (const struct tomoyo_condition_element *) (cond + 1);
366 struct tomoyo_number_union *numbers_p 363 struct tomoyo_number_union *numbers_p
367 = (struct tomoyo_number_union *) (condp + condc); 364 = (struct tomoyo_number_union *) (condp + condc);
368 struct tomoyo_name_union *names_p 365 struct tomoyo_name_union *names_p
369 = (struct tomoyo_name_union *) (numbers_p + numbers_count); 366 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
370 const struct tomoyo_argv *argv 367 const struct tomoyo_argv *argv
371 = (const struct tomoyo_argv *) (names_p + names_count); 368 = (const struct tomoyo_argv *) (names_p + names_count);
372 const struct tomoyo_envp *envp 369 const struct tomoyo_envp *envp
373 = (const struct tomoyo_envp *) (argv + argc); 370 = (const struct tomoyo_envp *) (argv + argc);
374 for (i = 0; i < numbers_count; i++) 371 for (i = 0; i < numbers_count; i++)
375 tomoyo_put_number_union(numbers_p++); 372 tomoyo_put_number_union(numbers_p++);
376 for (i = 0; i < names_count; i++) 373 for (i = 0; i < names_count; i++)
377 tomoyo_put_name_union(names_p++); 374 tomoyo_put_name_union(names_p++);
378 for (i = 0; i < argc; argv++, i++) 375 for (i = 0; i < argc; argv++, i++)
379 tomoyo_put_name(argv->value); 376 tomoyo_put_name(argv->value);
380 for (i = 0; i < envc; envp++, i++) { 377 for (i = 0; i < envc; envp++, i++) {
381 tomoyo_put_name(envp->name); 378 tomoyo_put_name(envp->name);
382 tomoyo_put_name(envp->value); 379 tomoyo_put_name(envp->value);
383 } 380 }
384 } 381 }
385 382
386 /** 383 /**
387 * tomoyo_del_name - Delete members in "struct tomoyo_name". 384 * tomoyo_del_name - Delete members in "struct tomoyo_name".
388 * 385 *
389 * @element: Pointer to "struct list_head". 386 * @element: Pointer to "struct list_head".
390 * 387 *
391 * Returns nothing. 388 * Returns nothing.
392 */ 389 */
393 static void tomoyo_del_name(struct list_head *element) 390 static void tomoyo_del_name(struct list_head *element)
394 { 391 {
395 const struct tomoyo_name *ptr = 392 const struct tomoyo_name *ptr =
396 container_of(element, typeof(*ptr), head.list); 393 container_of(element, typeof(*ptr), head.list);
397 } 394 }
398 395
399 /** 396 /**
400 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group". 397 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
401 * 398 *
402 * @element: Pointer to "struct list_head". 399 * @element: Pointer to "struct list_head".
403 * 400 *
404 * Returns nothing. 401 * Returns nothing.
405 */ 402 */
406 static void tomoyo_del_path_group(struct list_head *element) 403 static void tomoyo_del_path_group(struct list_head *element)
407 { 404 {
408 struct tomoyo_path_group *member = 405 struct tomoyo_path_group *member =
409 container_of(element, typeof(*member), head.list); 406 container_of(element, typeof(*member), head.list);
410 tomoyo_put_name(member->member_name); 407 tomoyo_put_name(member->member_name);
411 } 408 }
412 409
413 /** 410 /**
414 * tomoyo_del_group - Delete "struct tomoyo_group". 411 * tomoyo_del_group - Delete "struct tomoyo_group".
415 * 412 *
416 * @element: Pointer to "struct list_head". 413 * @element: Pointer to "struct list_head".
417 * 414 *
418 * Returns nothing. 415 * Returns nothing.
419 */ 416 */
420 static void tomoyo_del_group(struct list_head *element) 417 static void tomoyo_del_group(struct list_head *element)
421 { 418 {
422 struct tomoyo_group *group = 419 struct tomoyo_group *group =
423 container_of(element, typeof(*group), head.list); 420 container_of(element, typeof(*group), head.list);
424 tomoyo_put_name(group->group_name); 421 tomoyo_put_name(group->group_name);
425 } 422 }
426 423
427 /** 424 /**
428 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group". 425 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
429 * 426 *
430 * @element: Pointer to "struct list_head". 427 * @element: Pointer to "struct list_head".
431 * 428 *
432 * Returns nothing. 429 * Returns nothing.
433 */ 430 */
434 static void tomoyo_del_number_group(struct list_head *element) 431 static void tomoyo_del_number_group(struct list_head *element)
435 { 432 {
436 struct tomoyo_number_group *member = 433 struct tomoyo_number_group *member =
437 container_of(element, typeof(*member), head.list); 434 container_of(element, typeof(*member), head.list);
438 } 435 }
439 436
440 /** 437 /**
441 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head". 438 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
442 * 439 *
443 * @id: One of values in "enum tomoyo_policy_id". 440 * @id: One of values in "enum tomoyo_policy_id".
444 * @member_list: Pointer to "struct list_head". 441 * @member_list: Pointer to "struct list_head".
445 * 442 *
446 * Returns true if some elements are deleted, false otherwise. 443 * Returns true if some elements are deleted, false otherwise.
447 */ 444 */
448 static bool tomoyo_collect_member(const enum tomoyo_policy_id id, 445 static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
449 struct list_head *member_list) 446 struct list_head *member_list)
450 { 447 {
451 struct tomoyo_acl_head *member; 448 struct tomoyo_acl_head *member;
452 list_for_each_entry(member, member_list, list) { 449 list_for_each_entry(member, member_list, list) {
453 if (!member->is_deleted) 450 if (!member->is_deleted)
454 continue; 451 continue;
455 if (!tomoyo_add_to_gc(id, &member->list)) 452 if (!tomoyo_add_to_gc(id, &member->list))
456 return false; 453 return false;
457 } 454 }
458 return true; 455 return true;
459 } 456 }
460 457
461 /** 458 /**
462 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info". 459 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
463 * 460 *
464 * @list: Pointer to "struct list_head". 461 * @list: Pointer to "struct list_head".
465 * 462 *
466 * Returns true if some elements are deleted, false otherwise. 463 * Returns true if some elements are deleted, false otherwise.
467 */ 464 */
468 static bool tomoyo_collect_acl(struct list_head *list) 465 static bool tomoyo_collect_acl(struct list_head *list)
469 { 466 {
470 struct tomoyo_acl_info *acl; 467 struct tomoyo_acl_info *acl;
471 list_for_each_entry(acl, list, list) { 468 list_for_each_entry(acl, list, list) {
472 if (!acl->is_deleted) 469 if (!acl->is_deleted)
473 continue; 470 continue;
474 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 471 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
475 return false; 472 return false;
476 } 473 }
477 return true; 474 return true;
478 } 475 }
479 476
480 /** 477 /**
481 * tomoyo_collect_entry - Scan lists for deleted elements. 478 * tomoyo_collect_entry - Scan lists for deleted elements.
482 * 479 *
483 * Returns nothing. 480 * Returns nothing.
484 */ 481 */
485 static void tomoyo_collect_entry(void) 482 static void tomoyo_collect_entry(void)
486 { 483 {
487 int i; 484 int i;
488 enum tomoyo_policy_id id; 485 enum tomoyo_policy_id id;
489 struct tomoyo_policy_namespace *ns; 486 struct tomoyo_policy_namespace *ns;
490 int idx; 487 int idx;
491 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 488 if (mutex_lock_interruptible(&tomoyo_policy_lock))
492 return; 489 return;
493 idx = tomoyo_read_lock(); 490 idx = tomoyo_read_lock();
494 { 491 {
495 struct tomoyo_domain_info *domain; 492 struct tomoyo_domain_info *domain;
496 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 493 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
497 if (!tomoyo_collect_acl(&domain->acl_info_list)) 494 if (!tomoyo_collect_acl(&domain->acl_info_list))
498 goto unlock; 495 goto unlock;
499 if (!domain->is_deleted || atomic_read(&domain->users)) 496 if (!domain->is_deleted || atomic_read(&domain->users))
500 continue; 497 continue;
501 /* 498 /*
502 * Nobody is referring this domain. But somebody may 499 * Nobody is referring this domain. But somebody may
503 * refer this domain after successful execve(). 500 * refer this domain after successful execve().
504 * We recheck domain->users after SRCU synchronization. 501 * We recheck domain->users after SRCU synchronization.
505 */ 502 */
506 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list)) 503 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
507 goto unlock; 504 goto unlock;
508 } 505 }
509 } 506 }
510 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) { 507 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
511 for (id = 0; id < TOMOYO_MAX_POLICY; id++) 508 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
512 if (!tomoyo_collect_member(id, &ns->policy_list[id])) 509 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
513 goto unlock; 510 goto unlock;
514 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 511 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
515 if (!tomoyo_collect_acl(&ns->acl_group[i])) 512 if (!tomoyo_collect_acl(&ns->acl_group[i]))
516 goto unlock; 513 goto unlock;
517 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 514 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
518 struct list_head *list = &ns->group_list[i]; 515 struct list_head *list = &ns->group_list[i];
519 struct tomoyo_group *group; 516 struct tomoyo_group *group;
520 switch (i) { 517 switch (i) {
521 case 0: 518 case 0:
522 id = TOMOYO_ID_PATH_GROUP; 519 id = TOMOYO_ID_PATH_GROUP;
523 break; 520 break;
524 default: 521 default:
525 id = TOMOYO_ID_NUMBER_GROUP; 522 id = TOMOYO_ID_NUMBER_GROUP;
526 break; 523 break;
527 } 524 }
528 list_for_each_entry(group, list, head.list) { 525 list_for_each_entry(group, list, head.list) {
529 if (!tomoyo_collect_member 526 if (!tomoyo_collect_member
530 (id, &group->member_list)) 527 (id, &group->member_list))
531 goto unlock; 528 goto unlock;
532 if (!list_empty(&group->member_list) || 529 if (!list_empty(&group->member_list) ||
533 atomic_read(&group->head.users)) 530 atomic_read(&group->head.users))
534 continue; 531 continue;
535 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, 532 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
536 &group->head.list)) 533 &group->head.list))
537 goto unlock; 534 goto unlock;
538 } 535 }
539 } 536 }
540 } 537 }
541 id = TOMOYO_ID_CONDITION; 538 id = TOMOYO_ID_CONDITION;
542 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) { 539 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
543 struct list_head *list = !i ? 540 struct list_head *list = !i ?
544 &tomoyo_condition_list : &tomoyo_name_list[i - 1]; 541 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
545 struct tomoyo_shared_acl_head *ptr; 542 struct tomoyo_shared_acl_head *ptr;
546 list_for_each_entry(ptr, list, list) { 543 list_for_each_entry(ptr, list, list) {
547 if (atomic_read(&ptr->users)) 544 if (atomic_read(&ptr->users))
548 continue; 545 continue;
549 if (!tomoyo_add_to_gc(id, &ptr->list)) 546 if (!tomoyo_add_to_gc(id, &ptr->list))
550 goto unlock; 547 goto unlock;
551 } 548 }
552 id = TOMOYO_ID_NAME; 549 id = TOMOYO_ID_NAME;
553 } 550 }
554 unlock: 551 unlock:
555 tomoyo_read_unlock(idx); 552 tomoyo_read_unlock(idx);
556 mutex_unlock(&tomoyo_policy_lock); 553 mutex_unlock(&tomoyo_policy_lock);
557 } 554 }
558 555
559 /** 556 /**
560 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list. 557 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
561 * 558 *
562 * Returns true if some entries were kfree()d, false otherwise. 559 * Returns true if some entries were kfree()d, false otherwise.
563 */ 560 */
564 static bool tomoyo_kfree_entry(void) 561 static bool tomoyo_kfree_entry(void)
565 { 562 {
566 struct tomoyo_gc *p; 563 struct tomoyo_gc *p;
567 struct tomoyo_gc *tmp; 564 struct tomoyo_gc *tmp;
568 bool result = false; 565 bool result = false;
569 566
570 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) { 567 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
571 struct list_head *element = p->element; 568 struct list_head *element = p->element;
572 569
573 /* 570 /*
574 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the 571 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
575 * list element became no longer reachable from the list which 572 * list element became no longer reachable from the list which
576 * the element was originally on (e.g. tomoyo_domain_list). 573 * the element was originally on (e.g. tomoyo_domain_list).
577 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees 574 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
578 * that the list element became no longer referenced by syscall 575 * that the list element became no longer referenced by syscall
579 * users. 576 * users.
580 * 577 *
581 * However, there are three users which may still be using the 578 * However, there are three users which may still be using the
582 * list element. We need to defer until all of these users 579 * list element. We need to defer until all of these users
583 * forget the list element. 580 * forget the list element.
584 * 581 *
585 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain, 582 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
586 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget 583 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
587 * the list element. 584 * the list element.
588 */ 585 */
589 if (tomoyo_struct_used_by_io_buffer(element)) 586 if (tomoyo_struct_used_by_io_buffer(element))
590 continue; 587 continue;
591 /* 588 /*
592 * Secondly, defer until all other elements in the 589 * Secondly, defer until all other elements in the
593 * tomoyo_gc_list list forget the list element. 590 * tomoyo_gc_list list forget the list element.
594 */ 591 */
595 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size)) 592 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
596 continue; 593 continue;
597 switch (p->type) { 594 switch (p->type) {
598 case TOMOYO_ID_TRANSITION_CONTROL: 595 case TOMOYO_ID_TRANSITION_CONTROL:
599 tomoyo_del_transition_control(element); 596 tomoyo_del_transition_control(element);
600 break; 597 break;
601 case TOMOYO_ID_AGGREGATOR: 598 case TOMOYO_ID_AGGREGATOR:
602 tomoyo_del_aggregator(element); 599 tomoyo_del_aggregator(element);
603 break; 600 break;
604 case TOMOYO_ID_MANAGER: 601 case TOMOYO_ID_MANAGER:
605 tomoyo_del_manager(element); 602 tomoyo_del_manager(element);
606 break; 603 break;
607 case TOMOYO_ID_CONDITION: 604 case TOMOYO_ID_CONDITION:
608 tomoyo_del_condition(element); 605 tomoyo_del_condition(element);
609 break; 606 break;
610 case TOMOYO_ID_NAME: 607 case TOMOYO_ID_NAME:
611 /* 608 /*
612 * Thirdly, defer until all "struct tomoyo_io_buffer" 609 * Thirdly, defer until all "struct tomoyo_io_buffer"
613 * ->r.w[] forget the list element. 610 * ->r.w[] forget the list element.
614 */ 611 */
615 if (tomoyo_name_used_by_io_buffer( 612 if (tomoyo_name_used_by_io_buffer(
616 container_of(element, typeof(struct tomoyo_name), 613 container_of(element, typeof(struct tomoyo_name),
617 head.list)->entry.name, p->size)) 614 head.list)->entry.name, p->size))
618 continue; 615 continue;
619 tomoyo_del_name(element); 616 tomoyo_del_name(element);
620 break; 617 break;
621 case TOMOYO_ID_ACL: 618 case TOMOYO_ID_ACL:
622 tomoyo_del_acl(element); 619 tomoyo_del_acl(element);
623 break; 620 break;
624 case TOMOYO_ID_DOMAIN: 621 case TOMOYO_ID_DOMAIN:
625 if (!tomoyo_del_domain(element)) 622 if (!tomoyo_del_domain(element))
626 continue; 623 continue;
627 break; 624 break;
628 case TOMOYO_ID_PATH_GROUP: 625 case TOMOYO_ID_PATH_GROUP:
629 tomoyo_del_path_group(element); 626 tomoyo_del_path_group(element);
630 break; 627 break;
631 case TOMOYO_ID_GROUP: 628 case TOMOYO_ID_GROUP:
632 tomoyo_del_group(element); 629 tomoyo_del_group(element);
633 break; 630 break;
634 case TOMOYO_ID_NUMBER_GROUP: 631 case TOMOYO_ID_NUMBER_GROUP:
635 tomoyo_del_number_group(element); 632 tomoyo_del_number_group(element);
636 break; 633 break;
637 case TOMOYO_MAX_POLICY: 634 case TOMOYO_MAX_POLICY:
638 break; 635 break;
639 } 636 }
640 tomoyo_memory_free(element); 637 tomoyo_memory_free(element);
641 list_del(&p->list); 638 list_del(&p->list);
642 kfree(p); 639 kfree(p);
643 tomoyo_gc_list_len--; 640 tomoyo_gc_list_len--;
644 result = true; 641 result = true;
645 } 642 }
646 return result; 643 return result;
647 } 644 }
648 645
649 /** 646 /**
650 * tomoyo_gc_thread - Garbage collector thread function. 647 * tomoyo_gc_thread - Garbage collector thread function.
651 * 648 *
652 * @unused: Unused. 649 * @unused: Unused.
653 * 650 *
654 * In case OOM-killer choose this thread for termination, we create this thread 651 * In case OOM-killer choose this thread for termination, we create this thread
655 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was 652 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
656 * close()d. 653 * close()d.
657 * 654 *
658 * Returns 0. 655 * Returns 0.
659 */ 656 */
660 static int tomoyo_gc_thread(void *unused) 657 static int tomoyo_gc_thread(void *unused)
661 { 658 {
662 /* Garbage collector thread is exclusive. */ 659 /* Garbage collector thread is exclusive. */
663 static DEFINE_MUTEX(tomoyo_gc_mutex); 660 static DEFINE_MUTEX(tomoyo_gc_mutex);
664 if (!mutex_trylock(&tomoyo_gc_mutex)) 661 if (!mutex_trylock(&tomoyo_gc_mutex))
665 goto out; 662 goto out;
666 daemonize("GC for TOMOYO"); 663 daemonize("GC for TOMOYO");
667 do { 664 do {
668 tomoyo_collect_entry(); 665 tomoyo_collect_entry();
669 if (list_empty(&tomoyo_gc_list)) 666 if (list_empty(&tomoyo_gc_list))
670 break; 667 break;
671 synchronize_srcu(&tomoyo_ss); 668 synchronize_srcu(&tomoyo_ss);
672 } while (tomoyo_kfree_entry()); 669 } while (tomoyo_kfree_entry());
673 { 670 {
674 struct tomoyo_io_buffer *head; 671 struct tomoyo_io_buffer *head;
675 struct tomoyo_io_buffer *tmp; 672 struct tomoyo_io_buffer *tmp;
676 673
677 spin_lock(&tomoyo_io_buffer_list_lock); 674 spin_lock(&tomoyo_io_buffer_list_lock);
678 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list, 675 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
679 list) { 676 list) {
680 if (head->users) 677 if (head->users)
681 continue; 678 continue;
682 list_del(&head->list); 679 list_del(&head->list);
683 kfree(head->read_buf); 680 kfree(head->read_buf);
684 kfree(head->write_buf); 681 kfree(head->write_buf);
685 kfree(head); 682 kfree(head);
686 } 683 }
687 spin_unlock(&tomoyo_io_buffer_list_lock); 684 spin_unlock(&tomoyo_io_buffer_list_lock);
688 } 685 }
689 mutex_unlock(&tomoyo_gc_mutex); 686 mutex_unlock(&tomoyo_gc_mutex);
690 out: 687 out:
691 /* This acts as do_exit(0). */ 688 /* This acts as do_exit(0). */
692 return 0; 689 return 0;
693 } 690 }
694 691
695 /** 692 /**
696 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users. 693 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
697 * 694 *
698 * @head: Pointer to "struct tomoyo_io_buffer". 695 * @head: Pointer to "struct tomoyo_io_buffer".
699 * @is_register: True if register, false if unregister. 696 * @is_register: True if register, false if unregister.
700 * 697 *
701 * Returns nothing. 698 * Returns nothing.
702 */ 699 */
703 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register) 700 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
704 { 701 {
705 bool is_write = false; 702 bool is_write = false;
706 703
707 spin_lock(&tomoyo_io_buffer_list_lock); 704 spin_lock(&tomoyo_io_buffer_list_lock);
708 if (is_register) { 705 if (is_register) {
709 head->users = 1; 706 head->users = 1;
710 list_add(&head->list, &tomoyo_io_buffer_list); 707 list_add(&head->list, &tomoyo_io_buffer_list);
711 } else { 708 } else {
712 is_write = head->write_buf != NULL; 709 is_write = head->write_buf != NULL;
713 if (!--head->users) { 710 if (!--head->users) {
714 list_del(&head->list); 711 list_del(&head->list);
715 kfree(head->read_buf); 712 kfree(head->read_buf);
716 kfree(head->write_buf); 713 kfree(head->write_buf);
717 kfree(head); 714 kfree(head);
718 } 715 }
719 } 716 }
720 spin_unlock(&tomoyo_io_buffer_list_lock); 717 spin_unlock(&tomoyo_io_buffer_list_lock);
721 if (is_write) { 718 if (is_write) {
722 struct task_struct *task = kthread_create(tomoyo_gc_thread, 719 struct task_struct *task = kthread_create(tomoyo_gc_thread,
723 NULL, 720 NULL,
724 "GC for TOMOYO"); 721 "GC for TOMOYO");
725 if (!IS_ERR(task)) 722 if (!IS_ERR(task))
726 wake_up_process(task); 723 wake_up_process(task);
727 } 724 }
728 } 725 }
729 726
security/tomoyo/group.c
1 /* 1 /*
2 * security/tomoyo/group.c 2 * security/tomoyo/group.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7 #include <linux/slab.h> 7 #include <linux/slab.h>
8 #include "common.h" 8 #include "common.h"
9 9
10 /**
11 * tomoyo_same_path_group - Check for duplicated "struct tomoyo_path_group" entry.
12 *
13 * @a: Pointer to "struct tomoyo_acl_head".
14 * @b: Pointer to "struct tomoyo_acl_head".
15 *
16 * Returns true if @a == @b, false otherwise.
17 */
10 static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a, 18 static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a,
11 const struct tomoyo_acl_head *b) 19 const struct tomoyo_acl_head *b)
12 { 20 {
13 return container_of(a, struct tomoyo_path_group, head)->member_name == 21 return container_of(a, struct tomoyo_path_group, head)->member_name ==
14 container_of(b, struct tomoyo_path_group, head)->member_name; 22 container_of(b, struct tomoyo_path_group, head)->member_name;
15 } 23 }
16 24
25 /**
26 * tomoyo_same_number_group - Check for duplicated "struct tomoyo_number_group" entry.
27 *
28 * @a: Pointer to "struct tomoyo_acl_head".
29 * @b: Pointer to "struct tomoyo_acl_head".
30 *
31 * Returns true if @a == @b, false otherwise.
32 */
17 static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, 33 static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
18 const struct tomoyo_acl_head *b) 34 const struct tomoyo_acl_head *b)
19 { 35 {
20 return !memcmp(&container_of(a, struct tomoyo_number_group, head) 36 return !memcmp(&container_of(a, struct tomoyo_number_group, head)
21 ->number, 37 ->number,
22 &container_of(b, struct tomoyo_number_group, head) 38 &container_of(b, struct tomoyo_number_group, head)
23 ->number, 39 ->number,
24 sizeof(container_of(a, struct tomoyo_number_group, head) 40 sizeof(container_of(a, struct tomoyo_number_group, head)
25 ->number)); 41 ->number));
26 } 42 }
27 43
28 /** 44 /**
29 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. 45 * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
30 * 46 *
31 * @param: Pointer to "struct tomoyo_acl_param". 47 * @param: Pointer to "struct tomoyo_acl_param".
32 * @type: Type of this group. 48 * @type: Type of this group.
33 * 49 *
34 * Returns 0 on success, negative value otherwise. 50 * Returns 0 on success, negative value otherwise.
35 */ 51 */
36 int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type) 52 int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type)
37 { 53 {
38 struct tomoyo_group *group = tomoyo_get_group(param, type); 54 struct tomoyo_group *group = tomoyo_get_group(param, type);
39 int error = -EINVAL; 55 int error = -EINVAL;
40 if (!group) 56 if (!group)
41 return -ENOMEM; 57 return -ENOMEM;
42 param->list = &group->member_list; 58 param->list = &group->member_list;
43 if (type == TOMOYO_PATH_GROUP) { 59 if (type == TOMOYO_PATH_GROUP) {
44 struct tomoyo_path_group e = { }; 60 struct tomoyo_path_group e = { };
45 e.member_name = tomoyo_get_name(tomoyo_read_token(param)); 61 e.member_name = tomoyo_get_name(tomoyo_read_token(param));
46 if (!e.member_name) { 62 if (!e.member_name) {
47 error = -ENOMEM; 63 error = -ENOMEM;
48 goto out; 64 goto out;
49 } 65 }
50 error = tomoyo_update_policy(&e.head, sizeof(e), param, 66 error = tomoyo_update_policy(&e.head, sizeof(e), param,
51 tomoyo_same_path_group); 67 tomoyo_same_path_group);
52 tomoyo_put_name(e.member_name); 68 tomoyo_put_name(e.member_name);
53 } else if (type == TOMOYO_NUMBER_GROUP) { 69 } else if (type == TOMOYO_NUMBER_GROUP) {
54 struct tomoyo_number_group e = { }; 70 struct tomoyo_number_group e = { };
55 if (param->data[0] == '@' || 71 if (param->data[0] == '@' ||
56 !tomoyo_parse_number_union(param, &e.number)) 72 !tomoyo_parse_number_union(param, &e.number))
57 goto out; 73 goto out;
58 error = tomoyo_update_policy(&e.head, sizeof(e), param, 74 error = tomoyo_update_policy(&e.head, sizeof(e), param,
59 tomoyo_same_number_group); 75 tomoyo_same_number_group);
60 /* 76 /*
61 * tomoyo_put_number_union() is not needed because 77 * tomoyo_put_number_union() is not needed because
62 * param->data[0] != '@'. 78 * param->data[0] != '@'.
63 */ 79 */
64 } 80 }
65 out: 81 out:
66 tomoyo_put_group(group); 82 tomoyo_put_group(group);
67 return error; 83 return error;
68 } 84 }
69 85
70 /** 86 /**
71 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. 87 * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
72 * 88 *
73 * @pathname: The name of pathname. 89 * @pathname: The name of pathname.
74 * @group: Pointer to "struct tomoyo_path_group". 90 * @group: Pointer to "struct tomoyo_path_group".
75 * 91 *
76 * Returns matched member's pathname if @pathname matches pathnames in @group, 92 * Returns matched member's pathname if @pathname matches pathnames in @group,
77 * NULL otherwise. 93 * NULL otherwise.
78 * 94 *
79 * Caller holds tomoyo_read_lock(). 95 * Caller holds tomoyo_read_lock().
80 */ 96 */
81 const struct tomoyo_path_info * 97 const struct tomoyo_path_info *
82 tomoyo_path_matches_group(const struct tomoyo_path_info *pathname, 98 tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
83 const struct tomoyo_group *group) 99 const struct tomoyo_group *group)
84 { 100 {
85 struct tomoyo_path_group *member; 101 struct tomoyo_path_group *member;
86 list_for_each_entry_rcu(member, &group->member_list, head.list) { 102 list_for_each_entry_rcu(member, &group->member_list, head.list) {
87 if (member->head.is_deleted) 103 if (member->head.is_deleted)
88 continue; 104 continue;
89 if (!tomoyo_path_matches_pattern(pathname, member->member_name)) 105 if (!tomoyo_path_matches_pattern(pathname, member->member_name))
90 continue; 106 continue;
91 return member->member_name; 107 return member->member_name;
92 } 108 }
93 return NULL; 109 return NULL;
94 } 110 }
95 111
96 /** 112 /**
97 * tomoyo_number_matches_group - Check whether the given number matches members of the given number group. 113 * tomoyo_number_matches_group - Check whether the given number matches members of the given number group.
98 * 114 *
99 * @min: Min number. 115 * @min: Min number.
100 * @max: Max number. 116 * @max: Max number.
101 * @group: Pointer to "struct tomoyo_number_group". 117 * @group: Pointer to "struct tomoyo_number_group".
102 * 118 *
103 * Returns true if @min and @max partially overlaps @group, false otherwise. 119 * Returns true if @min and @max partially overlaps @group, false otherwise.
104 * 120 *
105 * Caller holds tomoyo_read_lock(). 121 * Caller holds tomoyo_read_lock().
106 */ 122 */
107 bool tomoyo_number_matches_group(const unsigned long min, 123 bool tomoyo_number_matches_group(const unsigned long min,
108 const unsigned long max, 124 const unsigned long max,
109 const struct tomoyo_group *group) 125 const struct tomoyo_group *group)
110 { 126 {
111 struct tomoyo_number_group *member; 127 struct tomoyo_number_group *member;
112 bool matched = false; 128 bool matched = false;
113 list_for_each_entry_rcu(member, &group->member_list, head.list) { 129 list_for_each_entry_rcu(member, &group->member_list, head.list) {
114 if (member->head.is_deleted) 130 if (member->head.is_deleted)
115 continue; 131 continue;
116 if (min > member->number.values[1] || 132 if (min > member->number.values[1] ||
117 max < member->number.values[0]) 133 max < member->number.values[0])
118 continue; 134 continue;
119 matched = true; 135 matched = true;
120 break; 136 break;
121 } 137 }
122 return matched; 138 return matched;
123 } 139 }
124 140
security/tomoyo/load_policy.c
1 /* 1 /*
2 * security/tomoyo/load_policy.c 2 * security/tomoyo/load_policy.c
3 * 3 *
4 * Policy loader launcher for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include "common.h" 7 #include "common.h"
10 8
11 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 9 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
12 10
13 /* 11 /*
14 * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER) 12 * Path to the policy loader. (default = CONFIG_SECURITY_TOMOYO_POLICY_LOADER)
15 */ 13 */
16 static const char *tomoyo_loader; 14 static const char *tomoyo_loader;
17 15
18 /** 16 /**
19 * tomoyo_loader_setup - Set policy loader. 17 * tomoyo_loader_setup - Set policy loader.
20 * 18 *
21 * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ). 19 * @str: Program to use as a policy loader (e.g. /sbin/tomoyo-init ).
22 * 20 *
23 * Returns 0. 21 * Returns 0.
24 */ 22 */
25 static int __init tomoyo_loader_setup(char *str) 23 static int __init tomoyo_loader_setup(char *str)
26 { 24 {
27 tomoyo_loader = str; 25 tomoyo_loader = str;
28 return 0; 26 return 0;
29 } 27 }
30 28
31 __setup("TOMOYO_loader=", tomoyo_loader_setup); 29 __setup("TOMOYO_loader=", tomoyo_loader_setup);
32 30
33 /** 31 /**
34 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists. 32 * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
35 * 33 *
36 * Returns true if /sbin/tomoyo-init exists, false otherwise. 34 * Returns true if /sbin/tomoyo-init exists, false otherwise.
37 */ 35 */
38 static bool tomoyo_policy_loader_exists(void) 36 static bool tomoyo_policy_loader_exists(void)
39 { 37 {
40 struct path path; 38 struct path path;
41 if (!tomoyo_loader) 39 if (!tomoyo_loader)
42 tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER; 40 tomoyo_loader = CONFIG_SECURITY_TOMOYO_POLICY_LOADER;
43 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) { 41 if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
44 printk(KERN_INFO "Not activating Mandatory Access Control " 42 printk(KERN_INFO "Not activating Mandatory Access Control "
45 "as %s does not exist.\n", tomoyo_loader); 43 "as %s does not exist.\n", tomoyo_loader);
46 return false; 44 return false;
47 } 45 }
48 path_put(&path); 46 path_put(&path);
49 return true; 47 return true;
50 } 48 }
51 49
52 /* 50 /*
53 * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER) 51 * Path to the trigger. (default = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER)
54 */ 52 */
55 static const char *tomoyo_trigger; 53 static const char *tomoyo_trigger;
56 54
57 /** 55 /**
58 * tomoyo_trigger_setup - Set trigger for activation. 56 * tomoyo_trigger_setup - Set trigger for activation.
59 * 57 *
60 * @str: Program to use as an activation trigger (e.g. /sbin/init ). 58 * @str: Program to use as an activation trigger (e.g. /sbin/init ).
61 * 59 *
62 * Returns 0. 60 * Returns 0.
63 */ 61 */
64 static int __init tomoyo_trigger_setup(char *str) 62 static int __init tomoyo_trigger_setup(char *str)
65 { 63 {
66 tomoyo_trigger = str; 64 tomoyo_trigger = str;
67 return 0; 65 return 0;
68 } 66 }
69 67
70 __setup("TOMOYO_trigger=", tomoyo_trigger_setup); 68 __setup("TOMOYO_trigger=", tomoyo_trigger_setup);
71 69
72 /** 70 /**
73 * tomoyo_load_policy - Run external policy loader to load policy. 71 * tomoyo_load_policy - Run external policy loader to load policy.
74 * 72 *
75 * @filename: The program about to start. 73 * @filename: The program about to start.
76 * 74 *
77 * This function checks whether @filename is /sbin/init , and if so 75 * This function checks whether @filename is /sbin/init , and if so
78 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init 76 * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
79 * and then continues invocation of /sbin/init. 77 * and then continues invocation of /sbin/init.
80 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and 78 * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
81 * writes to /sys/kernel/security/tomoyo/ interfaces. 79 * writes to /sys/kernel/security/tomoyo/ interfaces.
82 * 80 *
83 * Returns nothing. 81 * Returns nothing.
84 */ 82 */
85 void tomoyo_load_policy(const char *filename) 83 void tomoyo_load_policy(const char *filename)
86 { 84 {
87 static bool done; 85 static bool done;
88 char *argv[2]; 86 char *argv[2];
89 char *envp[3]; 87 char *envp[3];
90 88
91 if (tomoyo_policy_loaded || done) 89 if (tomoyo_policy_loaded || done)
92 return; 90 return;
93 if (!tomoyo_trigger) 91 if (!tomoyo_trigger)
94 tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER; 92 tomoyo_trigger = CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER;
95 if (strcmp(filename, tomoyo_trigger)) 93 if (strcmp(filename, tomoyo_trigger))
96 return; 94 return;
97 if (!tomoyo_policy_loader_exists()) 95 if (!tomoyo_policy_loader_exists())
98 return; 96 return;
99 done = true; 97 done = true;
100 printk(KERN_INFO "Calling %s to load policy. Please wait.\n", 98 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
101 tomoyo_loader); 99 tomoyo_loader);
102 argv[0] = (char *) tomoyo_loader; 100 argv[0] = (char *) tomoyo_loader;
103 argv[1] = NULL; 101 argv[1] = NULL;
104 envp[0] = "HOME=/"; 102 envp[0] = "HOME=/";
105 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 103 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
106 envp[2] = NULL; 104 envp[2] = NULL;
107 call_usermodehelper(argv[0], argv, envp, 1); 105 call_usermodehelper(argv[0], argv, envp, 1);
108 tomoyo_check_profile(); 106 tomoyo_check_profile();
109 } 107 }
110 108
111 #endif 109 #endif
112 110
security/tomoyo/memory.c
1 /* 1 /*
2 * security/tomoyo/memory.c 2 * security/tomoyo/memory.c
3 * 3 *
4 * Memory management functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/hash.h> 7 #include <linux/hash.h>
10 #include <linux/slab.h> 8 #include <linux/slab.h>
11 #include "common.h" 9 #include "common.h"
12 10
13 /** 11 /**
14 * tomoyo_warn_oom - Print out of memory warning message. 12 * tomoyo_warn_oom - Print out of memory warning message.
15 * 13 *
16 * @function: Function's name. 14 * @function: Function's name.
17 */ 15 */
18 void tomoyo_warn_oom(const char *function) 16 void tomoyo_warn_oom(const char *function)
19 { 17 {
20 /* Reduce error messages. */ 18 /* Reduce error messages. */
21 static pid_t tomoyo_last_pid; 19 static pid_t tomoyo_last_pid;
22 const pid_t pid = current->pid; 20 const pid_t pid = current->pid;
23 if (tomoyo_last_pid != pid) { 21 if (tomoyo_last_pid != pid) {
24 printk(KERN_WARNING "ERROR: Out of memory at %s.\n", 22 printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
25 function); 23 function);
26 tomoyo_last_pid = pid; 24 tomoyo_last_pid = pid;
27 } 25 }
28 if (!tomoyo_policy_loaded) 26 if (!tomoyo_policy_loaded)
29 panic("MAC Initialization failed.\n"); 27 panic("MAC Initialization failed.\n");
30 } 28 }
31 29
32 /* Lock for protecting tomoyo_memory_used. */ 30 /* Lock for protecting tomoyo_memory_used. */
33 static DEFINE_SPINLOCK(tomoyo_policy_memory_lock); 31 static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
34 /* Memoy currently used by policy/audit log/query. */ 32 /* Memoy currently used by policy/audit log/query. */
35 unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 33 unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
36 /* Memory quota for "policy"/"audit log"/"query". */ 34 /* Memory quota for "policy"/"audit log"/"query". */
37 unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT]; 35 unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
38 36
39 /** 37 /**
40 * tomoyo_memory_ok - Check memory quota. 38 * tomoyo_memory_ok - Check memory quota.
41 * 39 *
42 * @ptr: Pointer to allocated memory. 40 * @ptr: Pointer to allocated memory.
43 * 41 *
44 * Returns true on success, false otherwise. 42 * Returns true on success, false otherwise.
45 * 43 *
46 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise. 44 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
47 */ 45 */
48 bool tomoyo_memory_ok(void *ptr) 46 bool tomoyo_memory_ok(void *ptr)
49 { 47 {
50 if (ptr) { 48 if (ptr) {
51 const size_t s = ksize(ptr); 49 const size_t s = ksize(ptr);
52 bool result; 50 bool result;
53 spin_lock(&tomoyo_policy_memory_lock); 51 spin_lock(&tomoyo_policy_memory_lock);
54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s; 52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
55 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] || 53 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
56 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <= 54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
57 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY]; 55 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY];
58 if (!result) 56 if (!result)
59 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s; 57 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
60 spin_unlock(&tomoyo_policy_memory_lock); 58 spin_unlock(&tomoyo_policy_memory_lock);
61 if (result) 59 if (result)
62 return true; 60 return true;
63 } 61 }
64 tomoyo_warn_oom(__func__); 62 tomoyo_warn_oom(__func__);
65 return false; 63 return false;
66 } 64 }
67 65
68 /** 66 /**
69 * tomoyo_commit_ok - Check memory quota. 67 * tomoyo_commit_ok - Check memory quota.
70 * 68 *
71 * @data: Data to copy from. 69 * @data: Data to copy from.
72 * @size: Size in byte. 70 * @size: Size in byte.
73 * 71 *
74 * Returns pointer to allocated memory on success, NULL otherwise. 72 * Returns pointer to allocated memory on success, NULL otherwise.
75 * @data is zero-cleared on success. 73 * @data is zero-cleared on success.
76 */ 74 */
77 void *tomoyo_commit_ok(void *data, const unsigned int size) 75 void *tomoyo_commit_ok(void *data, const unsigned int size)
78 { 76 {
79 void *ptr = kzalloc(size, GFP_NOFS); 77 void *ptr = kzalloc(size, GFP_NOFS);
80 if (tomoyo_memory_ok(ptr)) { 78 if (tomoyo_memory_ok(ptr)) {
81 memmove(ptr, data, size); 79 memmove(ptr, data, size);
82 memset(data, 0, size); 80 memset(data, 0, size);
83 return ptr; 81 return ptr;
84 } 82 }
85 kfree(ptr); 83 kfree(ptr);
86 return NULL; 84 return NULL;
87 } 85 }
88 86
89 /** 87 /**
90 * tomoyo_memory_free - Free memory for elements. 88 * tomoyo_memory_free - Free memory for elements.
91 * 89 *
92 * @ptr: Pointer to allocated memory. 90 * @ptr: Pointer to allocated memory.
93 */ 91 */
94 void tomoyo_memory_free(void *ptr) 92 void tomoyo_memory_free(void *ptr)
95 { 93 {
96 size_t s = ksize(ptr); 94 size_t s = ksize(ptr);
97 spin_lock(&tomoyo_policy_memory_lock); 95 spin_lock(&tomoyo_policy_memory_lock);
98 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s; 96 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
99 spin_unlock(&tomoyo_policy_memory_lock); 97 spin_unlock(&tomoyo_policy_memory_lock);
100 kfree(ptr); 98 kfree(ptr);
101 } 99 }
102 100
103 /** 101 /**
104 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group". 102 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
105 * 103 *
106 * @param: Pointer to "struct tomoyo_acl_param". 104 * @param: Pointer to "struct tomoyo_acl_param".
107 * @idx: Index number. 105 * @idx: Index number.
108 * 106 *
109 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise. 107 * Returns pointer to "struct tomoyo_group" on success, NULL otherwise.
110 */ 108 */
111 struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param, 109 struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
112 const u8 idx) 110 const u8 idx)
113 { 111 {
114 struct tomoyo_group e = { }; 112 struct tomoyo_group e = { };
115 struct tomoyo_group *group = NULL; 113 struct tomoyo_group *group = NULL;
116 struct list_head *list; 114 struct list_head *list;
117 const char *group_name = tomoyo_read_token(param); 115 const char *group_name = tomoyo_read_token(param);
118 bool found = false; 116 bool found = false;
119 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP) 117 if (!tomoyo_correct_word(group_name) || idx >= TOMOYO_MAX_GROUP)
120 return NULL; 118 return NULL;
121 e.group_name = tomoyo_get_name(group_name); 119 e.group_name = tomoyo_get_name(group_name);
122 if (!e.group_name) 120 if (!e.group_name)
123 return NULL; 121 return NULL;
124 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 122 if (mutex_lock_interruptible(&tomoyo_policy_lock))
125 goto out; 123 goto out;
126 list = &param->ns->group_list[idx]; 124 list = &param->ns->group_list[idx];
127 list_for_each_entry(group, list, head.list) { 125 list_for_each_entry(group, list, head.list) {
128 if (e.group_name != group->group_name) 126 if (e.group_name != group->group_name)
129 continue; 127 continue;
130 atomic_inc(&group->head.users); 128 atomic_inc(&group->head.users);
131 found = true; 129 found = true;
132 break; 130 break;
133 } 131 }
134 if (!found) { 132 if (!found) {
135 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e)); 133 struct tomoyo_group *entry = tomoyo_commit_ok(&e, sizeof(e));
136 if (entry) { 134 if (entry) {
137 INIT_LIST_HEAD(&entry->member_list); 135 INIT_LIST_HEAD(&entry->member_list);
138 atomic_set(&entry->head.users, 1); 136 atomic_set(&entry->head.users, 1);
139 list_add_tail_rcu(&entry->head.list, list); 137 list_add_tail_rcu(&entry->head.list, list);
140 group = entry; 138 group = entry;
141 found = true; 139 found = true;
142 } 140 }
143 } 141 }
144 mutex_unlock(&tomoyo_policy_lock); 142 mutex_unlock(&tomoyo_policy_lock);
145 out: 143 out:
146 tomoyo_put_name(e.group_name); 144 tomoyo_put_name(e.group_name);
147 return found ? group : NULL; 145 return found ? group : NULL;
148 } 146 }
149 147
150 /* 148 /*
151 * tomoyo_name_list is used for holding string data used by TOMOYO. 149 * tomoyo_name_list is used for holding string data used by TOMOYO.
152 * Since same string data is likely used for multiple times (e.g. 150 * Since same string data is likely used for multiple times (e.g.
153 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 151 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
154 * "const struct tomoyo_path_info *". 152 * "const struct tomoyo_path_info *".
155 */ 153 */
156 struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 154 struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
157 155
158 /** 156 /**
159 * tomoyo_get_name - Allocate permanent memory for string data. 157 * tomoyo_get_name - Allocate permanent memory for string data.
160 * 158 *
161 * @name: The string to store into the permernent memory. 159 * @name: The string to store into the permernent memory.
162 * 160 *
163 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 161 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
164 */ 162 */
165 const struct tomoyo_path_info *tomoyo_get_name(const char *name) 163 const struct tomoyo_path_info *tomoyo_get_name(const char *name)
166 { 164 {
167 struct tomoyo_name *ptr; 165 struct tomoyo_name *ptr;
168 unsigned int hash; 166 unsigned int hash;
169 int len; 167 int len;
170 struct list_head *head; 168 struct list_head *head;
171 169
172 if (!name) 170 if (!name)
173 return NULL; 171 return NULL;
174 len = strlen(name) + 1; 172 len = strlen(name) + 1;
175 hash = full_name_hash((const unsigned char *) name, len - 1); 173 hash = full_name_hash((const unsigned char *) name, len - 1);
176 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 174 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
177 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 175 if (mutex_lock_interruptible(&tomoyo_policy_lock))
178 return NULL; 176 return NULL;
179 list_for_each_entry(ptr, head, head.list) { 177 list_for_each_entry(ptr, head, head.list) {
180 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 178 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
181 continue; 179 continue;
182 atomic_inc(&ptr->head.users); 180 atomic_inc(&ptr->head.users);
183 goto out; 181 goto out;
184 } 182 }
185 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS); 183 ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
186 if (tomoyo_memory_ok(ptr)) { 184 if (tomoyo_memory_ok(ptr)) {
187 ptr->entry.name = ((char *) ptr) + sizeof(*ptr); 185 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
188 memmove((char *) ptr->entry.name, name, len); 186 memmove((char *) ptr->entry.name, name, len);
189 atomic_set(&ptr->head.users, 1); 187 atomic_set(&ptr->head.users, 1);
190 tomoyo_fill_path_info(&ptr->entry); 188 tomoyo_fill_path_info(&ptr->entry);
191 list_add_tail(&ptr->head.list, head); 189 list_add_tail(&ptr->head.list, head);
192 } else { 190 } else {
193 kfree(ptr); 191 kfree(ptr);
194 ptr = NULL; 192 ptr = NULL;
195 } 193 }
196 out: 194 out:
197 mutex_unlock(&tomoyo_policy_lock); 195 mutex_unlock(&tomoyo_policy_lock);
198 return ptr ? &ptr->entry : NULL; 196 return ptr ? &ptr->entry : NULL;
199 } 197 }
200 198
201 /* Initial namespace.*/ 199 /* Initial namespace.*/
202 struct tomoyo_policy_namespace tomoyo_kernel_namespace; 200 struct tomoyo_policy_namespace tomoyo_kernel_namespace;
203 201
204 /** 202 /**
205 * tomoyo_mm_init - Initialize mm related code. 203 * tomoyo_mm_init - Initialize mm related code.
206 */ 204 */
207 void __init tomoyo_mm_init(void) 205 void __init tomoyo_mm_init(void)
208 { 206 {
209 int idx; 207 int idx;
210 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++) 208 for (idx = 0; idx < TOMOYO_MAX_HASH; idx++)
211 INIT_LIST_HEAD(&tomoyo_name_list[idx]); 209 INIT_LIST_HEAD(&tomoyo_name_list[idx]);
212 tomoyo_kernel_namespace.name = "<kernel>"; 210 tomoyo_kernel_namespace.name = "<kernel>";
213 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace); 211 tomoyo_init_policy_namespace(&tomoyo_kernel_namespace);
214 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace; 212 tomoyo_kernel_domain.ns = &tomoyo_kernel_namespace;
215 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 213 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
216 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>"); 214 tomoyo_kernel_domain.domainname = tomoyo_get_name("<kernel>");
217 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 215 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
218 } 216 }
219 217
security/tomoyo/mount.c
1 /* 1 /*
2 * security/tomoyo/mount.c 2 * security/tomoyo/mount.c
3 * 3 *
4 * Copyright (C) 2005-2010 NTT DATA CORPORATION 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */ 5 */
6 6
7 #include <linux/slab.h> 7 #include <linux/slab.h>
8 #include "common.h" 8 #include "common.h"
9 9
10 /* String table for special mount operations. */ 10 /* String table for special mount operations. */
11 static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = { 11 static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = {
12 [TOMOYO_MOUNT_BIND] = "--bind", 12 [TOMOYO_MOUNT_BIND] = "--bind",
13 [TOMOYO_MOUNT_MOVE] = "--move", 13 [TOMOYO_MOUNT_MOVE] = "--move",
14 [TOMOYO_MOUNT_REMOUNT] = "--remount", 14 [TOMOYO_MOUNT_REMOUNT] = "--remount",
15 [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable", 15 [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
16 [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private", 16 [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private",
17 [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave", 17 [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave",
18 [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared", 18 [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared",
19 }; 19 };
20 20
21 /** 21 /**
22 * tomoyo_audit_mount_log - Audit mount log. 22 * tomoyo_audit_mount_log - Audit mount log.
23 * 23 *
24 * @r: Pointer to "struct tomoyo_request_info". 24 * @r: Pointer to "struct tomoyo_request_info".
25 * 25 *
26 * Returns 0 on success, negative value otherwise. 26 * Returns 0 on success, negative value otherwise.
27 */ 27 */
28 static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) 28 static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
29 { 29 {
30 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n", 30 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n",
31 r->param.mount.dev->name, 31 r->param.mount.dev->name,
32 r->param.mount.dir->name, 32 r->param.mount.dir->name,
33 r->param.mount.type->name, 33 r->param.mount.type->name,
34 r->param.mount.flags); 34 r->param.mount.flags);
35 } 35 }
36 36
37 /** 37 /**
38 * tomoyo_check_mount_acl - Check permission for path path path number operation. 38 * tomoyo_check_mount_acl - Check permission for path path path number operation.
39 * 39 *
40 * @r: Pointer to "struct tomoyo_request_info". 40 * @r: Pointer to "struct tomoyo_request_info".
41 * @ptr: Pointer to "struct tomoyo_acl_info". 41 * @ptr: Pointer to "struct tomoyo_acl_info".
42 * 42 *
43 * Returns true if granted, false otherwise. 43 * Returns true if granted, false otherwise.
44 */ 44 */
45 static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r, 45 static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
46 const struct tomoyo_acl_info *ptr) 46 const struct tomoyo_acl_info *ptr)
47 { 47 {
48 const struct tomoyo_mount_acl *acl = 48 const struct tomoyo_mount_acl *acl =
49 container_of(ptr, typeof(*acl), head); 49 container_of(ptr, typeof(*acl), head);
50 return tomoyo_compare_number_union(r->param.mount.flags, 50 return tomoyo_compare_number_union(r->param.mount.flags,
51 &acl->flags) && 51 &acl->flags) &&
52 tomoyo_compare_name_union(r->param.mount.type, 52 tomoyo_compare_name_union(r->param.mount.type,
53 &acl->fs_type) && 53 &acl->fs_type) &&
54 tomoyo_compare_name_union(r->param.mount.dir, 54 tomoyo_compare_name_union(r->param.mount.dir,
55 &acl->dir_name) && 55 &acl->dir_name) &&
56 (!r->param.mount.need_dev || 56 (!r->param.mount.need_dev ||
57 tomoyo_compare_name_union(r->param.mount.dev, 57 tomoyo_compare_name_union(r->param.mount.dev,
58 &acl->dev_name)); 58 &acl->dev_name));
59 } 59 }
60 60
61 /** 61 /**
62 * tomoyo_mount_acl - Check permission for mount() operation. 62 * tomoyo_mount_acl - Check permission for mount() operation.
63 * 63 *
64 * @r: Pointer to "struct tomoyo_request_info". 64 * @r: Pointer to "struct tomoyo_request_info".
65 * @dev_name: Name of device file. 65 * @dev_name: Name of device file. Maybe NULL.
66 * @dir: Pointer to "struct path". 66 * @dir: Pointer to "struct path".
67 * @type: Name of filesystem type. 67 * @type: Name of filesystem type.
68 * @flags: Mount options. 68 * @flags: Mount options.
69 * 69 *
70 * Returns 0 on success, negative value otherwise. 70 * Returns 0 on success, negative value otherwise.
71 * 71 *
72 * Caller holds tomoyo_read_lock(). 72 * Caller holds tomoyo_read_lock().
73 */ 73 */
74 static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, 74 static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
75 struct path *dir, const char *type, 75 struct path *dir, const char *type,
76 unsigned long flags) 76 unsigned long flags)
77 { 77 {
78 struct tomoyo_obj_info obj = { }; 78 struct tomoyo_obj_info obj = { };
79 struct path path; 79 struct path path;
80 struct file_system_type *fstype = NULL; 80 struct file_system_type *fstype = NULL;
81 const char *requested_type = NULL; 81 const char *requested_type = NULL;
82 const char *requested_dir_name = NULL; 82 const char *requested_dir_name = NULL;
83 const char *requested_dev_name = NULL; 83 const char *requested_dev_name = NULL;
84 struct tomoyo_path_info rtype; 84 struct tomoyo_path_info rtype;
85 struct tomoyo_path_info rdev; 85 struct tomoyo_path_info rdev;
86 struct tomoyo_path_info rdir; 86 struct tomoyo_path_info rdir;
87 int need_dev = 0; 87 int need_dev = 0;
88 int error = -ENOMEM; 88 int error = -ENOMEM;
89 r->obj = &obj; 89 r->obj = &obj;
90 90
91 /* Get fstype. */ 91 /* Get fstype. */
92 requested_type = tomoyo_encode(type); 92 requested_type = tomoyo_encode(type);
93 if (!requested_type) 93 if (!requested_type)
94 goto out; 94 goto out;
95 rtype.name = requested_type; 95 rtype.name = requested_type;
96 tomoyo_fill_path_info(&rtype); 96 tomoyo_fill_path_info(&rtype);
97 97
98 /* Get mount point. */ 98 /* Get mount point. */
99 obj.path2 = *dir; 99 obj.path2 = *dir;
100 requested_dir_name = tomoyo_realpath_from_path(dir); 100 requested_dir_name = tomoyo_realpath_from_path(dir);
101 if (!requested_dir_name) { 101 if (!requested_dir_name) {
102 error = -ENOMEM; 102 error = -ENOMEM;
103 goto out; 103 goto out;
104 } 104 }
105 rdir.name = requested_dir_name; 105 rdir.name = requested_dir_name;
106 tomoyo_fill_path_info(&rdir); 106 tomoyo_fill_path_info(&rdir);
107 107
108 /* Compare fs name. */ 108 /* Compare fs name. */
109 if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) { 109 if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) {
110 /* dev_name is ignored. */ 110 /* dev_name is ignored. */
111 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] || 111 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] ||
112 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] || 112 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] ||
113 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] || 113 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] ||
114 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) { 114 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) {
115 /* dev_name is ignored. */ 115 /* dev_name is ignored. */
116 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] || 116 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] ||
117 type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) { 117 type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
118 need_dev = -1; /* dev_name is a directory */ 118 need_dev = -1; /* dev_name is a directory */
119 } else { 119 } else {
120 fstype = get_fs_type(type); 120 fstype = get_fs_type(type);
121 if (!fstype) { 121 if (!fstype) {
122 error = -ENODEV; 122 error = -ENODEV;
123 goto out; 123 goto out;
124 } 124 }
125 if (fstype->fs_flags & FS_REQUIRES_DEV) 125 if (fstype->fs_flags & FS_REQUIRES_DEV)
126 /* dev_name is a block device file. */ 126 /* dev_name is a block device file. */
127 need_dev = 1; 127 need_dev = 1;
128 } 128 }
129 if (need_dev) { 129 if (need_dev) {
130 /* Get mount point or device file. */ 130 /* Get mount point or device file. */
131 if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) { 131 if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
132 error = -ENOENT; 132 error = -ENOENT;
133 goto out; 133 goto out;
134 } 134 }
135 obj.path1 = path; 135 obj.path1 = path;
136 requested_dev_name = tomoyo_realpath_from_path(&path); 136 requested_dev_name = tomoyo_realpath_from_path(&path);
137 if (!requested_dev_name) { 137 if (!requested_dev_name) {
138 error = -ENOENT; 138 error = -ENOENT;
139 goto out; 139 goto out;
140 } 140 }
141 } else { 141 } else {
142 /* Map dev_name to "<NULL>" if no dev_name given. */ 142 /* Map dev_name to "<NULL>" if no dev_name given. */
143 if (!dev_name) 143 if (!dev_name)
144 dev_name = "<NULL>"; 144 dev_name = "<NULL>";
145 requested_dev_name = tomoyo_encode(dev_name); 145 requested_dev_name = tomoyo_encode(dev_name);
146 if (!requested_dev_name) { 146 if (!requested_dev_name) {
147 error = -ENOMEM; 147 error = -ENOMEM;
148 goto out; 148 goto out;
149 } 149 }
150 } 150 }
151 rdev.name = requested_dev_name; 151 rdev.name = requested_dev_name;
152 tomoyo_fill_path_info(&rdev); 152 tomoyo_fill_path_info(&rdev);
153 r->param_type = TOMOYO_TYPE_MOUNT_ACL; 153 r->param_type = TOMOYO_TYPE_MOUNT_ACL;
154 r->param.mount.need_dev = need_dev; 154 r->param.mount.need_dev = need_dev;
155 r->param.mount.dev = &rdev; 155 r->param.mount.dev = &rdev;
156 r->param.mount.dir = &rdir; 156 r->param.mount.dir = &rdir;
157 r->param.mount.type = &rtype; 157 r->param.mount.type = &rtype;
158 r->param.mount.flags = flags; 158 r->param.mount.flags = flags;
159 do { 159 do {
160 tomoyo_check_acl(r, tomoyo_check_mount_acl); 160 tomoyo_check_acl(r, tomoyo_check_mount_acl);
161 error = tomoyo_audit_mount_log(r); 161 error = tomoyo_audit_mount_log(r);
162 } while (error == TOMOYO_RETRY_REQUEST); 162 } while (error == TOMOYO_RETRY_REQUEST);
163 out: 163 out:
164 kfree(requested_dev_name); 164 kfree(requested_dev_name);
165 kfree(requested_dir_name); 165 kfree(requested_dir_name);
166 if (fstype) 166 if (fstype)
167 put_filesystem(fstype); 167 put_filesystem(fstype);
168 kfree(requested_type); 168 kfree(requested_type);
169 /* Drop refcount obtained by kern_path(). */ 169 /* Drop refcount obtained by kern_path(). */
170 if (obj.path1.dentry) 170 if (obj.path1.dentry)
171 path_put(&obj.path1); 171 path_put(&obj.path1);
172 return error; 172 return error;
173 } 173 }
174 174
175 /** 175 /**
176 * tomoyo_mount_permission - Check permission for mount() operation. 176 * tomoyo_mount_permission - Check permission for mount() operation.
177 * 177 *
178 * @dev_name: Name of device file. 178 * @dev_name: Name of device file. Maybe NULL.
179 * @path: Pointer to "struct path". 179 * @path: Pointer to "struct path".
180 * @type: Name of filesystem type. May be NULL. 180 * @type: Name of filesystem type. Maybe NULL.
181 * @flags: Mount options. 181 * @flags: Mount options.
182 * @data_page: Optional data. May be NULL. 182 * @data_page: Optional data. Maybe NULL.
183 * 183 *
184 * Returns 0 on success, negative value otherwise. 184 * Returns 0 on success, negative value otherwise.
185 */ 185 */
186 int tomoyo_mount_permission(char *dev_name, struct path *path, 186 int tomoyo_mount_permission(char *dev_name, struct path *path,
187 const char *type, unsigned long flags, 187 const char *type, unsigned long flags,
188 void *data_page) 188 void *data_page)
189 { 189 {
190 struct tomoyo_request_info r; 190 struct tomoyo_request_info r;
191 int error; 191 int error;
192 int idx; 192 int idx;
193 193
194 if (tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_MOUNT) 194 if (tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_MOUNT)
195 == TOMOYO_CONFIG_DISABLED) 195 == TOMOYO_CONFIG_DISABLED)
196 return 0; 196 return 0;
197 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) 197 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
198 flags &= ~MS_MGC_MSK; 198 flags &= ~MS_MGC_MSK;
199 if (flags & MS_REMOUNT) { 199 if (flags & MS_REMOUNT) {
200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]; 200 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
201 flags &= ~MS_REMOUNT; 201 flags &= ~MS_REMOUNT;
202 } 202 }
203 if (flags & MS_MOVE) { 203 if (flags & MS_MOVE) {
204 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE]; 204 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
205 flags &= ~MS_MOVE; 205 flags &= ~MS_MOVE;
206 } 206 }
207 if (flags & MS_BIND) { 207 if (flags & MS_BIND) {
208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND]; 208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
209 flags &= ~MS_BIND; 209 flags &= ~MS_BIND;
210 } 210 }
211 if (flags & MS_UNBINDABLE) { 211 if (flags & MS_UNBINDABLE) {
212 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE]; 212 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
213 flags &= ~MS_UNBINDABLE; 213 flags &= ~MS_UNBINDABLE;
214 } 214 }
215 if (flags & MS_PRIVATE) { 215 if (flags & MS_PRIVATE) {
216 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE]; 216 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
217 flags &= ~MS_PRIVATE; 217 flags &= ~MS_PRIVATE;
218 } 218 }
219 if (flags & MS_SLAVE) { 219 if (flags & MS_SLAVE) {
220 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE]; 220 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
221 flags &= ~MS_SLAVE; 221 flags &= ~MS_SLAVE;
222 } 222 }
223 if (flags & MS_SHARED) { 223 if (flags & MS_SHARED) {
224 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]; 224 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
225 flags &= ~MS_SHARED; 225 flags &= ~MS_SHARED;
226 } 226 }
227 if (!type) 227 if (!type)
228 type = "<NULL>"; 228 type = "<NULL>";
229 idx = tomoyo_read_lock(); 229 idx = tomoyo_read_lock();
230 error = tomoyo_mount_acl(&r, dev_name, path, type, flags); 230 error = tomoyo_mount_acl(&r, dev_name, path, type, flags);
231 tomoyo_read_unlock(idx); 231 tomoyo_read_unlock(idx);
232 return error; 232 return error;
233 } 233 }
234 234
security/tomoyo/realpath.c
1 /* 1 /*
2 * security/tomoyo/realpath.c 2 * security/tomoyo/realpath.c
3 * 3 *
4 * Pathname calculation functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/types.h> 7 #include <linux/types.h>
10 #include <linux/mount.h> 8 #include <linux/mount.h>
11 #include <linux/mnt_namespace.h> 9 #include <linux/mnt_namespace.h>
12 #include <linux/fs_struct.h> 10 #include <linux/fs_struct.h>
13 #include <linux/magic.h> 11 #include <linux/magic.h>
14 #include <linux/slab.h> 12 #include <linux/slab.h>
15 #include <net/sock.h> 13 #include <net/sock.h>
16 #include "common.h" 14 #include "common.h"
17 #include "../../fs/internal.h" 15 #include "../../fs/internal.h"
18 16
19 /** 17 /**
20 * tomoyo_encode: Convert binary string to ascii string. 18 * tomoyo_encode: Convert binary string to ascii string.
21 * 19 *
22 * @str: String in binary format. 20 * @str: String in binary format.
23 * 21 *
24 * Returns pointer to @str in ascii format on success, NULL otherwise. 22 * Returns pointer to @str in ascii format on success, NULL otherwise.
25 * 23 *
26 * This function uses kzalloc(), so caller must kfree() if this function 24 * This function uses kzalloc(), so caller must kfree() if this function
27 * didn't return NULL. 25 * didn't return NULL.
28 */ 26 */
29 char *tomoyo_encode(const char *str) 27 char *tomoyo_encode(const char *str)
30 { 28 {
31 int len = 0; 29 int len = 0;
32 const char *p = str; 30 const char *p = str;
33 char *cp; 31 char *cp;
34 char *cp0; 32 char *cp0;
35 33
36 if (!p) 34 if (!p)
37 return NULL; 35 return NULL;
38 while (*p) { 36 while (*p) {
39 const unsigned char c = *p++; 37 const unsigned char c = *p++;
40 if (c == '\\') 38 if (c == '\\')
41 len += 2; 39 len += 2;
42 else if (c > ' ' && c < 127) 40 else if (c > ' ' && c < 127)
43 len++; 41 len++;
44 else 42 else
45 len += 4; 43 len += 4;
46 } 44 }
47 len++; 45 len++;
48 /* Reserve space for appending "/". */ 46 /* Reserve space for appending "/". */
49 cp = kzalloc(len + 10, GFP_NOFS); 47 cp = kzalloc(len + 10, GFP_NOFS);
50 if (!cp) 48 if (!cp)
51 return NULL; 49 return NULL;
52 cp0 = cp; 50 cp0 = cp;
53 p = str; 51 p = str;
54 while (*p) { 52 while (*p) {
55 const unsigned char c = *p++; 53 const unsigned char c = *p++;
56 54
57 if (c == '\\') { 55 if (c == '\\') {
58 *cp++ = '\\'; 56 *cp++ = '\\';
59 *cp++ = '\\'; 57 *cp++ = '\\';
60 } else if (c > ' ' && c < 127) { 58 } else if (c > ' ' && c < 127) {
61 *cp++ = c; 59 *cp++ = c;
62 } else { 60 } else {
63 *cp++ = '\\'; 61 *cp++ = '\\';
64 *cp++ = (c >> 6) + '0'; 62 *cp++ = (c >> 6) + '0';
65 *cp++ = ((c >> 3) & 7) + '0'; 63 *cp++ = ((c >> 3) & 7) + '0';
66 *cp++ = (c & 7) + '0'; 64 *cp++ = (c & 7) + '0';
67 } 65 }
68 } 66 }
69 return cp0; 67 return cp0;
70 } 68 }
71 69
72 /** 70 /**
73 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root. 71 * tomoyo_get_absolute_path - Get the path of a dentry but ignores chroot'ed root.
74 * 72 *
75 * @path: Pointer to "struct path". 73 * @path: Pointer to "struct path".
76 * @buffer: Pointer to buffer to return value in. 74 * @buffer: Pointer to buffer to return value in.
77 * @buflen: Sizeof @buffer. 75 * @buflen: Sizeof @buffer.
78 * 76 *
79 * Returns the buffer on success, an error code otherwise. 77 * Returns the buffer on success, an error code otherwise.
80 * 78 *
81 * If dentry is a directory, trailing '/' is appended. 79 * If dentry is a directory, trailing '/' is appended.
82 */ 80 */
83 static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, 81 static char *tomoyo_get_absolute_path(struct path *path, char * const buffer,
84 const int buflen) 82 const int buflen)
85 { 83 {
86 char *pos = ERR_PTR(-ENOMEM); 84 char *pos = ERR_PTR(-ENOMEM);
87 if (buflen >= 256) { 85 if (buflen >= 256) {
88 struct path ns_root = { }; 86 struct path ns_root = { };
89 /* go to whatever namespace root we are under */ 87 /* go to whatever namespace root we are under */
90 pos = __d_path(path, &ns_root, buffer, buflen - 1); 88 pos = __d_path(path, &ns_root, buffer, buflen - 1);
91 if (!IS_ERR(pos) && *pos == '/' && pos[1]) { 89 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
92 struct inode *inode = path->dentry->d_inode; 90 struct inode *inode = path->dentry->d_inode;
93 if (inode && S_ISDIR(inode->i_mode)) { 91 if (inode && S_ISDIR(inode->i_mode)) {
94 buffer[buflen - 2] = '/'; 92 buffer[buflen - 2] = '/';
95 buffer[buflen - 1] = '\0'; 93 buffer[buflen - 1] = '\0';
96 } 94 }
97 } 95 }
98 } 96 }
99 return pos; 97 return pos;
100 } 98 }
101 99
102 /** 100 /**
103 * tomoyo_get_dentry_path - Get the path of a dentry. 101 * tomoyo_get_dentry_path - Get the path of a dentry.
104 * 102 *
105 * @dentry: Pointer to "struct dentry". 103 * @dentry: Pointer to "struct dentry".
106 * @buffer: Pointer to buffer to return value in. 104 * @buffer: Pointer to buffer to return value in.
107 * @buflen: Sizeof @buffer. 105 * @buflen: Sizeof @buffer.
108 * 106 *
109 * Returns the buffer on success, an error code otherwise. 107 * Returns the buffer on success, an error code otherwise.
110 * 108 *
111 * If dentry is a directory, trailing '/' is appended. 109 * If dentry is a directory, trailing '/' is appended.
112 */ 110 */
113 static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer, 111 static char *tomoyo_get_dentry_path(struct dentry *dentry, char * const buffer,
114 const int buflen) 112 const int buflen)
115 { 113 {
116 char *pos = ERR_PTR(-ENOMEM); 114 char *pos = ERR_PTR(-ENOMEM);
117 if (buflen >= 256) { 115 if (buflen >= 256) {
118 pos = dentry_path_raw(dentry, buffer, buflen - 1); 116 pos = dentry_path_raw(dentry, buffer, buflen - 1);
119 if (!IS_ERR(pos) && *pos == '/' && pos[1]) { 117 if (!IS_ERR(pos) && *pos == '/' && pos[1]) {
120 struct inode *inode = dentry->d_inode; 118 struct inode *inode = dentry->d_inode;
121 if (inode && S_ISDIR(inode->i_mode)) { 119 if (inode && S_ISDIR(inode->i_mode)) {
122 buffer[buflen - 2] = '/'; 120 buffer[buflen - 2] = '/';
123 buffer[buflen - 1] = '\0'; 121 buffer[buflen - 1] = '\0';
124 } 122 }
125 } 123 }
126 } 124 }
127 return pos; 125 return pos;
128 } 126 }
129 127
130 /** 128 /**
131 * tomoyo_get_local_path - Get the path of a dentry. 129 * tomoyo_get_local_path - Get the path of a dentry.
132 * 130 *
133 * @dentry: Pointer to "struct dentry". 131 * @dentry: Pointer to "struct dentry".
134 * @buffer: Pointer to buffer to return value in. 132 * @buffer: Pointer to buffer to return value in.
135 * @buflen: Sizeof @buffer. 133 * @buflen: Sizeof @buffer.
136 * 134 *
137 * Returns the buffer on success, an error code otherwise. 135 * Returns the buffer on success, an error code otherwise.
138 */ 136 */
139 static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, 137 static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer,
140 const int buflen) 138 const int buflen)
141 { 139 {
142 struct super_block *sb = dentry->d_sb; 140 struct super_block *sb = dentry->d_sb;
143 char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen); 141 char *pos = tomoyo_get_dentry_path(dentry, buffer, buflen);
144 if (IS_ERR(pos)) 142 if (IS_ERR(pos))
145 return pos; 143 return pos;
146 /* Convert from $PID to self if $PID is current thread. */ 144 /* Convert from $PID to self if $PID is current thread. */
147 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') { 145 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
148 char *ep; 146 char *ep;
149 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10); 147 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
150 if (*ep == '/' && pid && pid == 148 if (*ep == '/' && pid && pid ==
151 task_tgid_nr_ns(current, sb->s_fs_info)) { 149 task_tgid_nr_ns(current, sb->s_fs_info)) {
152 pos = ep - 5; 150 pos = ep - 5;
153 if (pos < buffer) 151 if (pos < buffer)
154 goto out; 152 goto out;
155 memmove(pos, "/self", 5); 153 memmove(pos, "/self", 5);
156 } 154 }
157 goto prepend_filesystem_name; 155 goto prepend_filesystem_name;
158 } 156 }
159 /* Use filesystem name for unnamed devices. */ 157 /* Use filesystem name for unnamed devices. */
160 if (!MAJOR(sb->s_dev)) 158 if (!MAJOR(sb->s_dev))
161 goto prepend_filesystem_name; 159 goto prepend_filesystem_name;
162 { 160 {
163 struct inode *inode = sb->s_root->d_inode; 161 struct inode *inode = sb->s_root->d_inode;
164 /* 162 /*
165 * Use filesystem name if filesystem does not support rename() 163 * Use filesystem name if filesystem does not support rename()
166 * operation. 164 * operation.
167 */ 165 */
168 if (inode->i_op && !inode->i_op->rename) 166 if (inode->i_op && !inode->i_op->rename)
169 goto prepend_filesystem_name; 167 goto prepend_filesystem_name;
170 } 168 }
171 /* Prepend device name. */ 169 /* Prepend device name. */
172 { 170 {
173 char name[64]; 171 char name[64];
174 int name_len; 172 int name_len;
175 const dev_t dev = sb->s_dev; 173 const dev_t dev = sb->s_dev;
176 name[sizeof(name) - 1] = '\0'; 174 name[sizeof(name) - 1] = '\0';
177 snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev), 175 snprintf(name, sizeof(name) - 1, "dev(%u,%u):", MAJOR(dev),
178 MINOR(dev)); 176 MINOR(dev));
179 name_len = strlen(name); 177 name_len = strlen(name);
180 pos -= name_len; 178 pos -= name_len;
181 if (pos < buffer) 179 if (pos < buffer)
182 goto out; 180 goto out;
183 memmove(pos, name, name_len); 181 memmove(pos, name, name_len);
184 return pos; 182 return pos;
185 } 183 }
186 /* Prepend filesystem name. */ 184 /* Prepend filesystem name. */
187 prepend_filesystem_name: 185 prepend_filesystem_name:
188 { 186 {
189 const char *name = sb->s_type->name; 187 const char *name = sb->s_type->name;
190 const int name_len = strlen(name); 188 const int name_len = strlen(name);
191 pos -= name_len + 1; 189 pos -= name_len + 1;
192 if (pos < buffer) 190 if (pos < buffer)
193 goto out; 191 goto out;
194 memmove(pos, name, name_len); 192 memmove(pos, name, name_len);
195 pos[name_len] = ':'; 193 pos[name_len] = ':';
196 } 194 }
197 return pos; 195 return pos;
198 out: 196 out:
199 return ERR_PTR(-ENOMEM); 197 return ERR_PTR(-ENOMEM);
200 } 198 }
201 199
202 /** 200 /**
203 * tomoyo_get_socket_name - Get the name of a socket. 201 * tomoyo_get_socket_name - Get the name of a socket.
204 * 202 *
205 * @path: Pointer to "struct path". 203 * @path: Pointer to "struct path".
206 * @buffer: Pointer to buffer to return value in. 204 * @buffer: Pointer to buffer to return value in.
207 * @buflen: Sizeof @buffer. 205 * @buflen: Sizeof @buffer.
208 * 206 *
209 * Returns the buffer. 207 * Returns the buffer.
210 */ 208 */
211 static char *tomoyo_get_socket_name(struct path *path, char * const buffer, 209 static char *tomoyo_get_socket_name(struct path *path, char * const buffer,
212 const int buflen) 210 const int buflen)
213 { 211 {
214 struct inode *inode = path->dentry->d_inode; 212 struct inode *inode = path->dentry->d_inode;
215 struct socket *sock = inode ? SOCKET_I(inode) : NULL; 213 struct socket *sock = inode ? SOCKET_I(inode) : NULL;
216 struct sock *sk = sock ? sock->sk : NULL; 214 struct sock *sk = sock ? sock->sk : NULL;
217 if (sk) { 215 if (sk) {
218 snprintf(buffer, buflen, "socket:[family=%u:type=%u:" 216 snprintf(buffer, buflen, "socket:[family=%u:type=%u:"
219 "protocol=%u]", sk->sk_family, sk->sk_type, 217 "protocol=%u]", sk->sk_family, sk->sk_type,
220 sk->sk_protocol); 218 sk->sk_protocol);
221 } else { 219 } else {
222 snprintf(buffer, buflen, "socket:[unknown]"); 220 snprintf(buffer, buflen, "socket:[unknown]");
223 } 221 }
224 return buffer; 222 return buffer;
225 } 223 }
226 224
227 /** 225 /**
228 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. 226 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
229 * 227 *
230 * @path: Pointer to "struct path". 228 * @path: Pointer to "struct path".
231 * 229 *
232 * Returns the realpath of the given @path on success, NULL otherwise. 230 * Returns the realpath of the given @path on success, NULL otherwise.
233 * 231 *
234 * If dentry is a directory, trailing '/' is appended. 232 * If dentry is a directory, trailing '/' is appended.
235 * Characters out of 0x20 < c < 0x7F range are converted to 233 * Characters out of 0x20 < c < 0x7F range are converted to
236 * \ooo style octal string. 234 * \ooo style octal string.
237 * Character \ is converted to \\ string. 235 * Character \ is converted to \\ string.
238 * 236 *
239 * These functions use kzalloc(), so the caller must call kfree() 237 * These functions use kzalloc(), so the caller must call kfree()
240 * if these functions didn't return NULL. 238 * if these functions didn't return NULL.
241 */ 239 */
242 char *tomoyo_realpath_from_path(struct path *path) 240 char *tomoyo_realpath_from_path(struct path *path)
243 { 241 {
244 char *buf = NULL; 242 char *buf = NULL;
245 char *name = NULL; 243 char *name = NULL;
246 unsigned int buf_len = PAGE_SIZE / 2; 244 unsigned int buf_len = PAGE_SIZE / 2;
247 struct dentry *dentry = path->dentry; 245 struct dentry *dentry = path->dentry;
248 struct super_block *sb; 246 struct super_block *sb;
249 if (!dentry) 247 if (!dentry)
250 return NULL; 248 return NULL;
251 sb = dentry->d_sb; 249 sb = dentry->d_sb;
252 while (1) { 250 while (1) {
253 char *pos; 251 char *pos;
254 struct inode *inode; 252 struct inode *inode;
255 buf_len <<= 1; 253 buf_len <<= 1;
256 kfree(buf); 254 kfree(buf);
257 buf = kmalloc(buf_len, GFP_NOFS); 255 buf = kmalloc(buf_len, GFP_NOFS);
258 if (!buf) 256 if (!buf)
259 break; 257 break;
260 /* To make sure that pos is '\0' terminated. */ 258 /* To make sure that pos is '\0' terminated. */
261 buf[buf_len - 1] = '\0'; 259 buf[buf_len - 1] = '\0';
262 /* Get better name for socket. */ 260 /* Get better name for socket. */
263 if (sb->s_magic == SOCKFS_MAGIC) { 261 if (sb->s_magic == SOCKFS_MAGIC) {
264 pos = tomoyo_get_socket_name(path, buf, buf_len - 1); 262 pos = tomoyo_get_socket_name(path, buf, buf_len - 1);
265 goto encode; 263 goto encode;
266 } 264 }
267 /* For "pipe:[\$]". */ 265 /* For "pipe:[\$]". */
268 if (dentry->d_op && dentry->d_op->d_dname) { 266 if (dentry->d_op && dentry->d_op->d_dname) {
269 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1); 267 pos = dentry->d_op->d_dname(dentry, buf, buf_len - 1);
270 goto encode; 268 goto encode;
271 } 269 }
272 inode = sb->s_root->d_inode; 270 inode = sb->s_root->d_inode;
273 /* 271 /*
274 * Get local name for filesystems without rename() operation 272 * Get local name for filesystems without rename() operation
275 * or dentry without vfsmount. 273 * or dentry without vfsmount.
276 */ 274 */
277 if (!path->mnt || (inode->i_op && !inode->i_op->rename)) 275 if (!path->mnt || (inode->i_op && !inode->i_op->rename))
278 pos = tomoyo_get_local_path(path->dentry, buf, 276 pos = tomoyo_get_local_path(path->dentry, buf,
279 buf_len - 1); 277 buf_len - 1);
280 /* Get absolute name for the rest. */ 278 /* Get absolute name for the rest. */
281 else 279 else
282 pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); 280 pos = tomoyo_get_absolute_path(path, buf, buf_len - 1);
283 encode: 281 encode:
284 if (IS_ERR(pos)) 282 if (IS_ERR(pos))
285 continue; 283 continue;
286 name = tomoyo_encode(pos); 284 name = tomoyo_encode(pos);
287 break; 285 break;
288 } 286 }
289 kfree(buf); 287 kfree(buf);
290 if (!name) 288 if (!name)
291 tomoyo_warn_oom(__func__); 289 tomoyo_warn_oom(__func__);
292 return name; 290 return name;
293 } 291 }
294 292
295 /** 293 /**
296 * tomoyo_realpath_nofollow - Get realpath of a pathname. 294 * tomoyo_realpath_nofollow - Get realpath of a pathname.
297 * 295 *
298 * @pathname: The pathname to solve. 296 * @pathname: The pathname to solve.
299 * 297 *
300 * Returns the realpath of @pathname on success, NULL otherwise. 298 * Returns the realpath of @pathname on success, NULL otherwise.
301 */ 299 */
302 char *tomoyo_realpath_nofollow(const char *pathname) 300 char *tomoyo_realpath_nofollow(const char *pathname)
303 { 301 {
304 struct path path; 302 struct path path;
305 303
306 if (pathname && kern_path(pathname, 0, &path) == 0) { 304 if (pathname && kern_path(pathname, 0, &path) == 0) {
307 char *buf = tomoyo_realpath_from_path(&path); 305 char *buf = tomoyo_realpath_from_path(&path);
308 path_put(&path); 306 path_put(&path);
309 return buf; 307 return buf;
310 } 308 }
311 return NULL; 309 return NULL;
312 } 310 }
313 311
security/tomoyo/securityfs_if.c
1 /* 1 /*
2 * security/tomoyo/common.c 2 * security/tomoyo/securityfs_if.c
3 * 3 *
4 * Securityfs interface for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/security.h> 7 #include <linux/security.h>
10 #include "common.h" 8 #include "common.h"
11 9
12 /** 10 /**
13 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 11 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
14 * 12 *
15 * @inode: Pointer to "struct inode". 13 * @inode: Pointer to "struct inode".
16 * @file: Pointer to "struct file". 14 * @file: Pointer to "struct file".
17 * 15 *
18 * Returns 0 on success, negative value otherwise. 16 * Returns 0 on success, negative value otherwise.
19 */ 17 */
20 static int tomoyo_open(struct inode *inode, struct file *file) 18 static int tomoyo_open(struct inode *inode, struct file *file)
21 { 19 {
22 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private) 20 const int key = ((u8 *) file->f_path.dentry->d_inode->i_private)
23 - ((u8 *) NULL); 21 - ((u8 *) NULL);
24 return tomoyo_open_control(key, file); 22 return tomoyo_open_control(key, file);
25 } 23 }
26 24
27 /** 25 /**
28 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface. 26 * tomoyo_release - close() for /sys/kernel/security/tomoyo/ interface.
29 * 27 *
30 * @inode: Pointer to "struct inode". 28 * @inode: Pointer to "struct inode".
31 * @file: Pointer to "struct file". 29 * @file: Pointer to "struct file".
32 * 30 *
33 * Returns 0 on success, negative value otherwise. 31 * Returns 0 on success, negative value otherwise.
34 */ 32 */
35 static int tomoyo_release(struct inode *inode, struct file *file) 33 static int tomoyo_release(struct inode *inode, struct file *file)
36 { 34 {
37 return tomoyo_close_control(file->private_data); 35 return tomoyo_close_control(file->private_data);
38 } 36 }
39 37
40 /** 38 /**
41 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface. 39 * tomoyo_poll - poll() for /sys/kernel/security/tomoyo/ interface.
42 * 40 *
43 * @file: Pointer to "struct file". 41 * @file: Pointer to "struct file".
44 * @wait: Pointer to "poll_table". 42 * @wait: Pointer to "poll_table".
45 * 43 *
46 * Returns 0 on success, negative value otherwise. 44 * Returns 0 on success, negative value otherwise.
47 */ 45 */
48 static unsigned int tomoyo_poll(struct file *file, poll_table *wait) 46 static unsigned int tomoyo_poll(struct file *file, poll_table *wait)
49 { 47 {
50 return tomoyo_poll_control(file, wait); 48 return tomoyo_poll_control(file, wait);
51 } 49 }
52 50
53 /** 51 /**
54 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface. 52 * tomoyo_read - read() for /sys/kernel/security/tomoyo/ interface.
55 * 53 *
56 * @file: Pointer to "struct file". 54 * @file: Pointer to "struct file".
57 * @buf: Pointer to buffer. 55 * @buf: Pointer to buffer.
58 * @count: Size of @buf. 56 * @count: Size of @buf.
59 * @ppos: Unused. 57 * @ppos: Unused.
60 * 58 *
61 * Returns bytes read on success, negative value otherwise. 59 * Returns bytes read on success, negative value otherwise.
62 */ 60 */
63 static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count, 61 static ssize_t tomoyo_read(struct file *file, char __user *buf, size_t count,
64 loff_t *ppos) 62 loff_t *ppos)
65 { 63 {
66 return tomoyo_read_control(file->private_data, buf, count); 64 return tomoyo_read_control(file->private_data, buf, count);
67 } 65 }
68 66
69 /** 67 /**
70 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface. 68 * tomoyo_write - write() for /sys/kernel/security/tomoyo/ interface.
71 * 69 *
72 * @file: Pointer to "struct file". 70 * @file: Pointer to "struct file".
73 * @buf: Pointer to buffer. 71 * @buf: Pointer to buffer.
74 * @count: Size of @buf. 72 * @count: Size of @buf.
75 * @ppos: Unused. 73 * @ppos: Unused.
76 * 74 *
77 * Returns @count on success, negative value otherwise. 75 * Returns @count on success, negative value otherwise.
78 */ 76 */
79 static ssize_t tomoyo_write(struct file *file, const char __user *buf, 77 static ssize_t tomoyo_write(struct file *file, const char __user *buf,
80 size_t count, loff_t *ppos) 78 size_t count, loff_t *ppos)
81 { 79 {
82 return tomoyo_write_control(file->private_data, buf, count); 80 return tomoyo_write_control(file->private_data, buf, count);
83 } 81 }
84 82
85 /* 83 /*
86 * tomoyo_operations is a "struct file_operations" which is used for handling 84 * tomoyo_operations is a "struct file_operations" which is used for handling
87 * /sys/kernel/security/tomoyo/ interface. 85 * /sys/kernel/security/tomoyo/ interface.
88 * 86 *
89 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR). 87 * Some files under /sys/kernel/security/tomoyo/ directory accept open(O_RDWR).
90 * See tomoyo_io_buffer for internals. 88 * See tomoyo_io_buffer for internals.
91 */ 89 */
92 static const struct file_operations tomoyo_operations = { 90 static const struct file_operations tomoyo_operations = {
93 .open = tomoyo_open, 91 .open = tomoyo_open,
94 .release = tomoyo_release, 92 .release = tomoyo_release,
95 .poll = tomoyo_poll, 93 .poll = tomoyo_poll,
96 .read = tomoyo_read, 94 .read = tomoyo_read,
97 .write = tomoyo_write, 95 .write = tomoyo_write,
98 .llseek = noop_llseek, 96 .llseek = noop_llseek,
99 }; 97 };
100 98
101 /** 99 /**
102 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory. 100 * tomoyo_create_entry - Create interface files under /sys/kernel/security/tomoyo/ directory.
103 * 101 *
104 * @name: The name of the interface file. 102 * @name: The name of the interface file.
105 * @mode: The permission of the interface file. 103 * @mode: The permission of the interface file.
106 * @parent: The parent directory. 104 * @parent: The parent directory.
107 * @key: Type of interface. 105 * @key: Type of interface.
108 * 106 *
109 * Returns nothing. 107 * Returns nothing.
110 */ 108 */
111 static void __init tomoyo_create_entry(const char *name, const mode_t mode, 109 static void __init tomoyo_create_entry(const char *name, const mode_t mode,
112 struct dentry *parent, const u8 key) 110 struct dentry *parent, const u8 key)
113 { 111 {
114 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key, 112 securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
115 &tomoyo_operations); 113 &tomoyo_operations);
116 } 114 }
117 115
118 /** 116 /**
119 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface. 117 * tomoyo_initerface_init - Initialize /sys/kernel/security/tomoyo/ interface.
120 * 118 *
121 * Returns 0. 119 * Returns 0.
122 */ 120 */
123 static int __init tomoyo_initerface_init(void) 121 static int __init tomoyo_initerface_init(void)
124 { 122 {
125 struct dentry *tomoyo_dir; 123 struct dentry *tomoyo_dir;
126 124
127 /* Don't create securityfs entries unless registered. */ 125 /* Don't create securityfs entries unless registered. */
128 if (current_cred()->security != &tomoyo_kernel_domain) 126 if (current_cred()->security != &tomoyo_kernel_domain)
129 return 0; 127 return 0;
130 128
131 tomoyo_dir = securityfs_create_dir("tomoyo", NULL); 129 tomoyo_dir = securityfs_create_dir("tomoyo", NULL);
132 tomoyo_create_entry("query", 0600, tomoyo_dir, 130 tomoyo_create_entry("query", 0600, tomoyo_dir,
133 TOMOYO_QUERY); 131 TOMOYO_QUERY);
134 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir, 132 tomoyo_create_entry("domain_policy", 0600, tomoyo_dir,
135 TOMOYO_DOMAINPOLICY); 133 TOMOYO_DOMAINPOLICY);
136 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir, 134 tomoyo_create_entry("exception_policy", 0600, tomoyo_dir,
137 TOMOYO_EXCEPTIONPOLICY); 135 TOMOYO_EXCEPTIONPOLICY);
138 tomoyo_create_entry("audit", 0400, tomoyo_dir, 136 tomoyo_create_entry("audit", 0400, tomoyo_dir,
139 TOMOYO_AUDIT); 137 TOMOYO_AUDIT);
140 tomoyo_create_entry("self_domain", 0400, tomoyo_dir, 138 tomoyo_create_entry("self_domain", 0400, tomoyo_dir,
141 TOMOYO_SELFDOMAIN); 139 TOMOYO_SELFDOMAIN);
142 tomoyo_create_entry(".process_status", 0600, tomoyo_dir, 140 tomoyo_create_entry(".process_status", 0600, tomoyo_dir,
143 TOMOYO_PROCESS_STATUS); 141 TOMOYO_PROCESS_STATUS);
144 tomoyo_create_entry("stat", 0644, tomoyo_dir, 142 tomoyo_create_entry("stat", 0644, tomoyo_dir,
145 TOMOYO_STAT); 143 TOMOYO_STAT);
146 tomoyo_create_entry("profile", 0600, tomoyo_dir, 144 tomoyo_create_entry("profile", 0600, tomoyo_dir,
147 TOMOYO_PROFILE); 145 TOMOYO_PROFILE);
148 tomoyo_create_entry("manager", 0600, tomoyo_dir, 146 tomoyo_create_entry("manager", 0600, tomoyo_dir,
149 TOMOYO_MANAGER); 147 TOMOYO_MANAGER);
150 tomoyo_create_entry("version", 0400, tomoyo_dir, 148 tomoyo_create_entry("version", 0400, tomoyo_dir,
151 TOMOYO_VERSION); 149 TOMOYO_VERSION);
152 return 0; 150 return 0;
153 } 151 }
154 152
155 fs_initcall(tomoyo_initerface_init); 153 fs_initcall(tomoyo_initerface_init);
156 154
security/tomoyo/tomoyo.c
1 /* 1 /*
2 * security/tomoyo/tomoyo.c 2 * security/tomoyo/tomoyo.c
3 * 3 *
4 * LSM hooks for TOMOYO Linux. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/security.h> 7 #include <linux/security.h>
10 #include "common.h" 8 #include "common.h"
11 9
10 /**
11 * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
12 *
13 * @new: Pointer to "struct cred".
14 * @gfp: Memory allocation flags.
15 *
16 * Returns 0.
17 */
12 static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 18 static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
13 { 19 {
14 new->security = NULL; 20 new->security = NULL;
15 return 0; 21 return 0;
16 } 22 }
17 23
24 /**
25 * tomoyo_cred_prepare - Target for security_prepare_creds().
26 *
27 * @new: Pointer to "struct cred".
28 * @old: Pointer to "struct cred".
29 * @gfp: Memory allocation flags.
30 *
31 * Returns 0.
32 */
18 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 33 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
19 gfp_t gfp) 34 gfp_t gfp)
20 { 35 {
21 struct tomoyo_domain_info *domain = old->security; 36 struct tomoyo_domain_info *domain = old->security;
22 new->security = domain; 37 new->security = domain;
23 if (domain) 38 if (domain)
24 atomic_inc(&domain->users); 39 atomic_inc(&domain->users);
25 return 0; 40 return 0;
26 } 41 }
27 42
43 /**
44 * tomoyo_cred_transfer - Target for security_transfer_creds().
45 *
46 * @new: Pointer to "struct cred".
47 * @old: Pointer to "struct cred".
48 */
28 static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 49 static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
29 { 50 {
30 tomoyo_cred_prepare(new, old, 0); 51 tomoyo_cred_prepare(new, old, 0);
31 } 52 }
32 53
54 /**
55 * tomoyo_cred_free - Target for security_cred_free().
56 *
57 * @cred: Pointer to "struct cred".
58 */
33 static void tomoyo_cred_free(struct cred *cred) 59 static void tomoyo_cred_free(struct cred *cred)
34 { 60 {
35 struct tomoyo_domain_info *domain = cred->security; 61 struct tomoyo_domain_info *domain = cred->security;
36 if (domain) 62 if (domain)
37 atomic_dec(&domain->users); 63 atomic_dec(&domain->users);
38 } 64 }
39 65
66 /**
67 * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
68 *
69 * @bprm: Pointer to "struct linux_binprm".
70 *
71 * Returns 0 on success, negative value otherwise.
72 */
40 static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 73 static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
41 { 74 {
42 int rc; 75 int rc;
43 76
44 rc = cap_bprm_set_creds(bprm); 77 rc = cap_bprm_set_creds(bprm);
45 if (rc) 78 if (rc)
46 return rc; 79 return rc;
47 80
48 /* 81 /*
49 * Do only if this function is called for the first time of an execve 82 * Do only if this function is called for the first time of an execve
50 * operation. 83 * operation.
51 */ 84 */
52 if (bprm->cred_prepared) 85 if (bprm->cred_prepared)
53 return 0; 86 return 0;
54 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER 87 #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
55 /* 88 /*
56 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested 89 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
57 * for the first time. 90 * for the first time.
58 */ 91 */
59 if (!tomoyo_policy_loaded) 92 if (!tomoyo_policy_loaded)
60 tomoyo_load_policy(bprm->filename); 93 tomoyo_load_policy(bprm->filename);
61 #endif 94 #endif
62 /* 95 /*
63 * Release reference to "struct tomoyo_domain_info" stored inside 96 * Release reference to "struct tomoyo_domain_info" stored inside
64 * "bprm->cred->security". New reference to "struct tomoyo_domain_info" 97 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
65 * stored inside "bprm->cred->security" will be acquired later inside 98 * stored inside "bprm->cred->security" will be acquired later inside
66 * tomoyo_find_next_domain(). 99 * tomoyo_find_next_domain().
67 */ 100 */
68 atomic_dec(&((struct tomoyo_domain_info *) 101 atomic_dec(&((struct tomoyo_domain_info *)
69 bprm->cred->security)->users); 102 bprm->cred->security)->users);
70 /* 103 /*
71 * Tell tomoyo_bprm_check_security() is called for the first time of an 104 * Tell tomoyo_bprm_check_security() is called for the first time of an
72 * execve operation. 105 * execve operation.
73 */ 106 */
74 bprm->cred->security = NULL; 107 bprm->cred->security = NULL;
75 return 0; 108 return 0;
76 } 109 }
77 110
111 /**
112 * tomoyo_bprm_check_security - Target for security_bprm_check().
113 *
114 * @bprm: Pointer to "struct linux_binprm".
115 *
116 * Returns 0 on success, negative value otherwise.
117 */
78 static int tomoyo_bprm_check_security(struct linux_binprm *bprm) 118 static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
79 { 119 {
80 struct tomoyo_domain_info *domain = bprm->cred->security; 120 struct tomoyo_domain_info *domain = bprm->cred->security;
81 121
82 /* 122 /*
83 * Execute permission is checked against pathname passed to do_execve() 123 * Execute permission is checked against pathname passed to do_execve()
84 * using current domain. 124 * using current domain.
85 */ 125 */
86 if (!domain) { 126 if (!domain) {
87 const int idx = tomoyo_read_lock(); 127 const int idx = tomoyo_read_lock();
88 const int err = tomoyo_find_next_domain(bprm); 128 const int err = tomoyo_find_next_domain(bprm);
89 tomoyo_read_unlock(idx); 129 tomoyo_read_unlock(idx);
90 return err; 130 return err;
91 } 131 }
92 /* 132 /*
93 * Read permission is checked against interpreters using next domain. 133 * Read permission is checked against interpreters using next domain.
94 */ 134 */
95 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY); 135 return tomoyo_check_open_permission(domain, &bprm->file->f_path,
136 O_RDONLY);
96 } 137 }
97 138
139 /**
140 * tomoyo_inode_getattr - Target for security_inode_getattr().
141 *
142 * @mnt: Pointer to "struct vfsmount".
143 * @dentry: Pointer to "struct dentry".
144 *
145 * Returns 0 on success, negative value otherwise.
146 */
98 static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 147 static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
99 { 148 {
100 struct path path = { mnt, dentry }; 149 struct path path = { mnt, dentry };
101 return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL); 150 return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
102 } 151 }
103 152
153 /**
154 * tomoyo_path_truncate - Target for security_path_truncate().
155 *
156 * @path: Pointer to "struct path".
157 *
158 * Returns 0 on success, negative value otherwise.
159 */
104 static int tomoyo_path_truncate(struct path *path) 160 static int tomoyo_path_truncate(struct path *path)
105 { 161 {
106 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL); 162 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
107 } 163 }
108 164
165 /**
166 * tomoyo_path_unlink - Target for security_path_unlink().
167 *
168 * @parent: Pointer to "struct path".
169 * @dentry: Pointer to "struct dentry".
170 *
171 * Returns 0 on success, negative value otherwise.
172 */
109 static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 173 static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
110 { 174 {
111 struct path path = { parent->mnt, dentry }; 175 struct path path = { parent->mnt, dentry };
112 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL); 176 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
113 } 177 }
114 178
179 /**
180 * tomoyo_path_mkdir - Target for security_path_mkdir().
181 *
182 * @parent: Pointer to "struct path".
183 * @dentry: Pointer to "struct dentry".
184 * @mode: DAC permission mode.
185 *
186 * Returns 0 on success, negative value otherwise.
187 */
115 static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 188 static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
116 int mode) 189 int mode)
117 { 190 {
118 struct path path = { parent->mnt, dentry }; 191 struct path path = { parent->mnt, dentry };
119 return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path, 192 return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
120 mode & S_IALLUGO); 193 mode & S_IALLUGO);
121 } 194 }
122 195
196 /**
197 * tomoyo_path_rmdir - Target for security_path_rmdir().
198 *
199 * @parent: Pointer to "struct path".
200 * @dentry: Pointer to "struct dentry".
201 *
202 * Returns 0 on success, negative value otherwise.
203 */
123 static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 204 static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
124 { 205 {
125 struct path path = { parent->mnt, dentry }; 206 struct path path = { parent->mnt, dentry };
126 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL); 207 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
127 } 208 }
128 209
210 /**
211 * tomoyo_path_symlink - Target for security_path_symlink().
212 *
213 * @parent: Pointer to "struct path".
214 * @dentry: Pointer to "struct dentry".
215 * @old_name: Symlink's content.
216 *
217 * Returns 0 on success, negative value otherwise.
218 */
129 static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 219 static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
130 const char *old_name) 220 const char *old_name)
131 { 221 {
132 struct path path = { parent->mnt, dentry }; 222 struct path path = { parent->mnt, dentry };
133 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name); 223 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
134 } 224 }
135 225
226 /**
227 * tomoyo_path_mknod - Target for security_path_mknod().
228 *
229 * @parent: Pointer to "struct path".
230 * @dentry: Pointer to "struct dentry".
231 * @mode: DAC permission mode.
232 * @dev: Device attributes.
233 *
234 * Returns 0 on success, negative value otherwise.
235 */
136 static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 236 static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
137 int mode, unsigned int dev) 237 int mode, unsigned int dev)
138 { 238 {
139 struct path path = { parent->mnt, dentry }; 239 struct path path = { parent->mnt, dentry };
140 int type = TOMOYO_TYPE_CREATE; 240 int type = TOMOYO_TYPE_CREATE;
141 const unsigned int perm = mode & S_IALLUGO; 241 const unsigned int perm = mode & S_IALLUGO;
142 242
143 switch (mode & S_IFMT) { 243 switch (mode & S_IFMT) {
144 case S_IFCHR: 244 case S_IFCHR:
145 type = TOMOYO_TYPE_MKCHAR; 245 type = TOMOYO_TYPE_MKCHAR;
146 break; 246 break;
147 case S_IFBLK: 247 case S_IFBLK:
148 type = TOMOYO_TYPE_MKBLOCK; 248 type = TOMOYO_TYPE_MKBLOCK;
149 break; 249 break;
150 default: 250 default:
151 goto no_dev; 251 goto no_dev;
152 } 252 }
153 return tomoyo_mkdev_perm(type, &path, perm, dev); 253 return tomoyo_mkdev_perm(type, &path, perm, dev);
154 no_dev: 254 no_dev:
155 switch (mode & S_IFMT) { 255 switch (mode & S_IFMT) {
156 case S_IFIFO: 256 case S_IFIFO:
157 type = TOMOYO_TYPE_MKFIFO; 257 type = TOMOYO_TYPE_MKFIFO;
158 break; 258 break;
159 case S_IFSOCK: 259 case S_IFSOCK:
160 type = TOMOYO_TYPE_MKSOCK; 260 type = TOMOYO_TYPE_MKSOCK;
161 break; 261 break;
162 } 262 }
163 return tomoyo_path_number_perm(type, &path, perm); 263 return tomoyo_path_number_perm(type, &path, perm);
164 } 264 }
165 265
266 /**
267 * tomoyo_path_link - Target for security_path_link().
268 *
269 * @old_dentry: Pointer to "struct dentry".
270 * @new_dir: Pointer to "struct path".
271 * @new_dentry: Pointer to "struct dentry".
272 *
273 * Returns 0 on success, negative value otherwise.
274 */
166 static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 275 static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
167 struct dentry *new_dentry) 276 struct dentry *new_dentry)
168 { 277 {
169 struct path path1 = { new_dir->mnt, old_dentry }; 278 struct path path1 = { new_dir->mnt, old_dentry };
170 struct path path2 = { new_dir->mnt, new_dentry }; 279 struct path path2 = { new_dir->mnt, new_dentry };
171 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2); 280 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
172 } 281 }
173 282
283 /**
284 * tomoyo_path_rename - Target for security_path_rename().
285 *
286 * @old_parent: Pointer to "struct path".
287 * @old_dentry: Pointer to "struct dentry".
288 * @new_parent: Pointer to "struct path".
289 * @new_dentry: Pointer to "struct dentry".
290 *
291 * Returns 0 on success, negative value otherwise.
292 */
174 static int tomoyo_path_rename(struct path *old_parent, 293 static int tomoyo_path_rename(struct path *old_parent,
175 struct dentry *old_dentry, 294 struct dentry *old_dentry,
176 struct path *new_parent, 295 struct path *new_parent,
177 struct dentry *new_dentry) 296 struct dentry *new_dentry)
178 { 297 {
179 struct path path1 = { old_parent->mnt, old_dentry }; 298 struct path path1 = { old_parent->mnt, old_dentry };
180 struct path path2 = { new_parent->mnt, new_dentry }; 299 struct path path2 = { new_parent->mnt, new_dentry };
181 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2); 300 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
182 } 301 }
183 302
303 /**
304 * tomoyo_file_fcntl - Target for security_file_fcntl().
305 *
306 * @file: Pointer to "struct file".
307 * @cmd: Command for fcntl().
308 * @arg: Argument for @cmd.
309 *
310 * Returns 0 on success, negative value otherwise.
311 */
184 static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 312 static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
185 unsigned long arg) 313 unsigned long arg)
186 { 314 {
187 if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))) 315 if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
188 return 0; 316 return 0;
189 return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path, 317 return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
190 O_WRONLY | (arg & O_APPEND)); 318 O_WRONLY | (arg & O_APPEND));
191 } 319 }
192 320
321 /**
322 * tomoyo_dentry_open - Target for security_dentry_open().
323 *
324 * @f: Pointer to "struct file".
325 * @cred: Pointer to "struct cred".
326 *
327 * Returns 0 on success, negative value otherwise.
328 */
193 static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 329 static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
194 { 330 {
195 int flags = f->f_flags; 331 int flags = f->f_flags;
196 /* Don't check read permission here if called from do_execve(). */ 332 /* Don't check read permission here if called from do_execve(). */
197 if (current->in_execve) 333 if (current->in_execve)
198 return 0; 334 return 0;
199 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 335 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
200 } 336 }
201 337
338 /**
339 * tomoyo_file_ioctl - Target for security_file_ioctl().
340 *
341 * @file: Pointer to "struct file".
342 * @cmd: Command for ioctl().
343 * @arg: Argument for @cmd.
344 *
345 * Returns 0 on success, negative value otherwise.
346 */
202 static int tomoyo_file_ioctl(struct file *file, unsigned int cmd, 347 static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
203 unsigned long arg) 348 unsigned long arg)
204 { 349 {
205 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd); 350 return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
206 } 351 }
207 352
353 /**
354 * tomoyo_path_chmod - Target for security_path_chmod().
355 *
356 * @dentry: Pointer to "struct dentry".
357 * @mnt: Pointer to "struct vfsmount".
358 * @mode: DAC permission mode.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
208 static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt, 362 static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
209 mode_t mode) 363 mode_t mode)
210 { 364 {
211 struct path path = { mnt, dentry }; 365 struct path path = { mnt, dentry };
212 return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, &path, 366 return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, &path,
213 mode & S_IALLUGO); 367 mode & S_IALLUGO);
214 } 368 }
215 369
370 /**
371 * tomoyo_path_chown - Target for security_path_chown().
372 *
373 * @path: Pointer to "struct path".
374 * @uid: Owner ID.
375 * @gid: Group ID.
376 *
377 * Returns 0 on success, negative value otherwise.
378 */
216 static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 379 static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
217 { 380 {
218 int error = 0; 381 int error = 0;
219 if (uid != (uid_t) -1) 382 if (uid != (uid_t) -1)
220 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid); 383 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid);
221 if (!error && gid != (gid_t) -1) 384 if (!error && gid != (gid_t) -1)
222 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid); 385 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid);
223 return error; 386 return error;
224 } 387 }
225 388
389 /**
390 * tomoyo_path_chroot - Target for security_path_chroot().
391 *
392 * @path: Pointer to "struct path".
393 *
394 * Returns 0 on success, negative value otherwise.
395 */
226 static int tomoyo_path_chroot(struct path *path) 396 static int tomoyo_path_chroot(struct path *path)
227 { 397 {
228 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL); 398 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
229 } 399 }
230 400
401 /**
402 * tomoyo_sb_mount - Target for security_sb_mount().
403 *
404 * @dev_name: Name of device file. Maybe NULL.
405 * @path: Pointer to "struct path".
406 * @type: Name of filesystem type. Maybe NULL.
407 * @flags: Mount options.
408 * @data: Optional data. Maybe NULL.
409 *
410 * Returns 0 on success, negative value otherwise.
411 */
231 static int tomoyo_sb_mount(char *dev_name, struct path *path, 412 static int tomoyo_sb_mount(char *dev_name, struct path *path,
232 char *type, unsigned long flags, void *data) 413 char *type, unsigned long flags, void *data)
233 { 414 {
234 return tomoyo_mount_permission(dev_name, path, type, flags, data); 415 return tomoyo_mount_permission(dev_name, path, type, flags, data);
235 } 416 }
236 417
418 /**
419 * tomoyo_sb_umount - Target for security_sb_umount().
420 *
421 * @mnt: Pointer to "struct vfsmount".
422 * @flags: Unmount options.
423 *
424 * Returns 0 on success, negative value otherwise.
425 */
237 static int tomoyo_sb_umount(struct vfsmount *mnt, int flags) 426 static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
238 { 427 {
239 struct path path = { mnt, mnt->mnt_root }; 428 struct path path = { mnt, mnt->mnt_root };
240 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL); 429 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
241 } 430 }
242 431
432 /**
433 * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
434 *
435 * @old_path: Pointer to "struct path".
436 * @new_path: Pointer to "struct path".
437 *
438 * Returns 0 on success, negative value otherwise.
439 */
243 static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path) 440 static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
244 { 441 {
245 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path); 442 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
246 } 443 }
247 444
248 /* 445 /*
249 * tomoyo_security_ops is a "struct security_operations" which is used for 446 * tomoyo_security_ops is a "struct security_operations" which is used for
250 * registering TOMOYO. 447 * registering TOMOYO.
251 */ 448 */
252 static struct security_operations tomoyo_security_ops = { 449 static struct security_operations tomoyo_security_ops = {
253 .name = "tomoyo", 450 .name = "tomoyo",
254 .cred_alloc_blank = tomoyo_cred_alloc_blank, 451 .cred_alloc_blank = tomoyo_cred_alloc_blank,
255 .cred_prepare = tomoyo_cred_prepare, 452 .cred_prepare = tomoyo_cred_prepare,
256 .cred_transfer = tomoyo_cred_transfer, 453 .cred_transfer = tomoyo_cred_transfer,
257 .cred_free = tomoyo_cred_free, 454 .cred_free = tomoyo_cred_free,
258 .bprm_set_creds = tomoyo_bprm_set_creds, 455 .bprm_set_creds = tomoyo_bprm_set_creds,
259 .bprm_check_security = tomoyo_bprm_check_security, 456 .bprm_check_security = tomoyo_bprm_check_security,
260 .file_fcntl = tomoyo_file_fcntl, 457 .file_fcntl = tomoyo_file_fcntl,
261 .dentry_open = tomoyo_dentry_open, 458 .dentry_open = tomoyo_dentry_open,
262 .path_truncate = tomoyo_path_truncate, 459 .path_truncate = tomoyo_path_truncate,
263 .path_unlink = tomoyo_path_unlink, 460 .path_unlink = tomoyo_path_unlink,
264 .path_mkdir = tomoyo_path_mkdir, 461 .path_mkdir = tomoyo_path_mkdir,
265 .path_rmdir = tomoyo_path_rmdir, 462 .path_rmdir = tomoyo_path_rmdir,
266 .path_symlink = tomoyo_path_symlink, 463 .path_symlink = tomoyo_path_symlink,
267 .path_mknod = tomoyo_path_mknod, 464 .path_mknod = tomoyo_path_mknod,
268 .path_link = tomoyo_path_link, 465 .path_link = tomoyo_path_link,
269 .path_rename = tomoyo_path_rename, 466 .path_rename = tomoyo_path_rename,
270 .inode_getattr = tomoyo_inode_getattr, 467 .inode_getattr = tomoyo_inode_getattr,
271 .file_ioctl = tomoyo_file_ioctl, 468 .file_ioctl = tomoyo_file_ioctl,
272 .path_chmod = tomoyo_path_chmod, 469 .path_chmod = tomoyo_path_chmod,
273 .path_chown = tomoyo_path_chown, 470 .path_chown = tomoyo_path_chown,
274 .path_chroot = tomoyo_path_chroot, 471 .path_chroot = tomoyo_path_chroot,
275 .sb_mount = tomoyo_sb_mount, 472 .sb_mount = tomoyo_sb_mount,
276 .sb_umount = tomoyo_sb_umount, 473 .sb_umount = tomoyo_sb_umount,
277 .sb_pivotroot = tomoyo_sb_pivotroot, 474 .sb_pivotroot = tomoyo_sb_pivotroot,
278 }; 475 };
279 476
280 /* Lock for GC. */ 477 /* Lock for GC. */
281 struct srcu_struct tomoyo_ss; 478 struct srcu_struct tomoyo_ss;
282 479
480 /**
481 * tomoyo_init - Register TOMOYO Linux as a LSM module.
482 *
483 * Returns 0.
484 */
283 static int __init tomoyo_init(void) 485 static int __init tomoyo_init(void)
284 { 486 {
285 struct cred *cred = (struct cred *) current_cred(); 487 struct cred *cred = (struct cred *) current_cred();
286 488
287 if (!security_module_enable(&tomoyo_security_ops)) 489 if (!security_module_enable(&tomoyo_security_ops))
288 return 0; 490 return 0;
289 /* register ourselves with the security framework */ 491 /* register ourselves with the security framework */
290 if (register_security(&tomoyo_security_ops) || 492 if (register_security(&tomoyo_security_ops) ||
291 init_srcu_struct(&tomoyo_ss)) 493 init_srcu_struct(&tomoyo_ss))
292 panic("Failure registering TOMOYO Linux"); 494 panic("Failure registering TOMOYO Linux");
293 printk(KERN_INFO "TOMOYO Linux initialized\n"); 495 printk(KERN_INFO "TOMOYO Linux initialized\n");
294 cred->security = &tomoyo_kernel_domain; 496 cred->security = &tomoyo_kernel_domain;
295 tomoyo_mm_init(); 497 tomoyo_mm_init();
296 return 0; 498 return 0;
297 } 499 }
298 500
security/tomoyo/util.c
1 /* 1 /*
2 * security/tomoyo/util.c 2 * security/tomoyo/util.c
3 * 3 *
4 * Utility functions for TOMOYO. 4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 */ 5 */
8 6
9 #include <linux/slab.h> 7 #include <linux/slab.h>
10 #include "common.h" 8 #include "common.h"
11 9
12 /* Lock for protecting policy. */ 10 /* Lock for protecting policy. */
13 DEFINE_MUTEX(tomoyo_policy_lock); 11 DEFINE_MUTEX(tomoyo_policy_lock);
14 12
15 /* Has /sbin/init started? */ 13 /* Has /sbin/init started? */
16 bool tomoyo_policy_loaded; 14 bool tomoyo_policy_loaded;
17 15
18 /* 16 /*
19 * Mapping table from "enum tomoyo_mac_index" to 17 * Mapping table from "enum tomoyo_mac_index" to
20 * "enum tomoyo_mac_category_index". 18 * "enum tomoyo_mac_category_index".
21 */ 19 */
22 const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = { 20 const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
23 /* CONFIG::file group */ 21 /* CONFIG::file group */
24 [TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE, 22 [TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE,
25 [TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE, 23 [TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE,
26 [TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE, 24 [TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE,
27 [TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE, 25 [TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE,
28 [TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE, 26 [TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE,
29 [TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE, 27 [TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE,
30 [TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE, 28 [TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE,
31 [TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE, 29 [TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE,
32 [TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE, 30 [TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE,
33 [TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE, 31 [TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE,
34 [TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE, 32 [TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE,
35 [TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE, 33 [TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE,
36 [TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE, 34 [TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE,
37 [TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE, 35 [TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE,
38 [TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE, 36 [TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE,
39 [TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE, 37 [TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE,
40 [TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE, 38 [TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE,
41 [TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE, 39 [TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE,
42 [TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE, 40 [TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE,
43 [TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE, 41 [TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE,
44 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE, 42 [TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
45 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE, 43 [TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
46 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE, 44 [TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
47 }; 45 };
48 46
49 /** 47 /**
50 * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss. 48 * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
51 * 49 *
52 * @time: Seconds since 1970/01/01 00:00:00. 50 * @time: Seconds since 1970/01/01 00:00:00.
53 * @stamp: Pointer to "struct tomoyo_time". 51 * @stamp: Pointer to "struct tomoyo_time".
54 * 52 *
55 * Returns nothing. 53 * Returns nothing.
56 * 54 *
57 * This function does not handle Y2038 problem. 55 * This function does not handle Y2038 problem.
58 */ 56 */
59 void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp) 57 void tomoyo_convert_time(time_t time, struct tomoyo_time *stamp)
60 { 58 {
61 static const u16 tomoyo_eom[2][12] = { 59 static const u16 tomoyo_eom[2][12] = {
62 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 60 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
63 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 61 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
64 }; 62 };
65 u16 y; 63 u16 y;
66 u8 m; 64 u8 m;
67 bool r; 65 bool r;
68 stamp->sec = time % 60; 66 stamp->sec = time % 60;
69 time /= 60; 67 time /= 60;
70 stamp->min = time % 60; 68 stamp->min = time % 60;
71 time /= 60; 69 time /= 60;
72 stamp->hour = time % 24; 70 stamp->hour = time % 24;
73 time /= 24; 71 time /= 24;
74 for (y = 1970; ; y++) { 72 for (y = 1970; ; y++) {
75 const unsigned short days = (y & 3) ? 365 : 366; 73 const unsigned short days = (y & 3) ? 365 : 366;
76 if (time < days) 74 if (time < days)
77 break; 75 break;
78 time -= days; 76 time -= days;
79 } 77 }
80 r = (y & 3) == 0; 78 r = (y & 3) == 0;
81 for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++) 79 for (m = 0; m < 11 && time >= tomoyo_eom[r][m]; m++)
82 ; 80 ;
83 if (m) 81 if (m)
84 time -= tomoyo_eom[r][m - 1]; 82 time -= tomoyo_eom[r][m - 1];
85 stamp->year = y; 83 stamp->year = y;
86 stamp->month = ++m; 84 stamp->month = ++m;
87 stamp->day = ++time; 85 stamp->day = ++time;
88 } 86 }
89 87
90 /** 88 /**
91 * tomoyo_permstr - Find permission keywords. 89 * tomoyo_permstr - Find permission keywords.
92 * 90 *
93 * @string: String representation for permissions in foo/bar/buz format. 91 * @string: String representation for permissions in foo/bar/buz format.
94 * @keyword: Keyword to find from @string/ 92 * @keyword: Keyword to find from @string/
95 * 93 *
96 * Returns ture if @keyword was found in @string, false otherwise. 94 * Returns ture if @keyword was found in @string, false otherwise.
97 * 95 *
98 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2. 96 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
99 */ 97 */
100 bool tomoyo_permstr(const char *string, const char *keyword) 98 bool tomoyo_permstr(const char *string, const char *keyword)
101 { 99 {
102 const char *cp = strstr(string, keyword); 100 const char *cp = strstr(string, keyword);
103 if (cp) 101 if (cp)
104 return cp == string || *(cp - 1) == '/'; 102 return cp == string || *(cp - 1) == '/';
105 return false; 103 return false;
106 } 104 }
107 105
108 /** 106 /**
109 * tomoyo_read_token - Read a word from a line. 107 * tomoyo_read_token - Read a word from a line.
110 * 108 *
111 * @param: Pointer to "struct tomoyo_acl_param". 109 * @param: Pointer to "struct tomoyo_acl_param".
112 * 110 *
113 * Returns a word on success, "" otherwise. 111 * Returns a word on success, "" otherwise.
114 * 112 *
115 * To allow the caller to skip NULL check, this function returns "" rather than 113 * To allow the caller to skip NULL check, this function returns "" rather than
116 * NULL if there is no more words to read. 114 * NULL if there is no more words to read.
117 */ 115 */
118 char *tomoyo_read_token(struct tomoyo_acl_param *param) 116 char *tomoyo_read_token(struct tomoyo_acl_param *param)
119 { 117 {
120 char *pos = param->data; 118 char *pos = param->data;
121 char *del = strchr(pos, ' '); 119 char *del = strchr(pos, ' ');
122 if (del) 120 if (del)
123 *del++ = '\0'; 121 *del++ = '\0';
124 else 122 else
125 del = pos + strlen(pos); 123 del = pos + strlen(pos);
126 param->data = del; 124 param->data = del;
127 return pos; 125 return pos;
128 } 126 }
129 127
130 /** 128 /**
131 * tomoyo_parse_ulong - Parse an "unsigned long" value. 129 * tomoyo_parse_ulong - Parse an "unsigned long" value.
132 * 130 *
133 * @result: Pointer to "unsigned long". 131 * @result: Pointer to "unsigned long".
134 * @str: Pointer to string to parse. 132 * @str: Pointer to string to parse.
135 * 133 *
136 * Returns one of values in "enum tomoyo_value_type". 134 * Returns one of values in "enum tomoyo_value_type".
137 * 135 *
138 * The @src is updated to point the first character after the value 136 * The @src is updated to point the first character after the value
139 * on success. 137 * on success.
140 */ 138 */
141 u8 tomoyo_parse_ulong(unsigned long *result, char **str) 139 u8 tomoyo_parse_ulong(unsigned long *result, char **str)
142 { 140 {
143 const char *cp = *str; 141 const char *cp = *str;
144 char *ep; 142 char *ep;
145 int base = 10; 143 int base = 10;
146 if (*cp == '0') { 144 if (*cp == '0') {
147 char c = *(cp + 1); 145 char c = *(cp + 1);
148 if (c == 'x' || c == 'X') { 146 if (c == 'x' || c == 'X') {
149 base = 16; 147 base = 16;
150 cp += 2; 148 cp += 2;
151 } else if (c >= '0' && c <= '7') { 149 } else if (c >= '0' && c <= '7') {
152 base = 8; 150 base = 8;
153 cp++; 151 cp++;
154 } 152 }
155 } 153 }
156 *result = simple_strtoul(cp, &ep, base); 154 *result = simple_strtoul(cp, &ep, base);
157 if (cp == ep) 155 if (cp == ep)
158 return TOMOYO_VALUE_TYPE_INVALID; 156 return TOMOYO_VALUE_TYPE_INVALID;
159 *str = ep; 157 *str = ep;
160 switch (base) { 158 switch (base) {
161 case 16: 159 case 16:
162 return TOMOYO_VALUE_TYPE_HEXADECIMAL; 160 return TOMOYO_VALUE_TYPE_HEXADECIMAL;
163 case 8: 161 case 8:
164 return TOMOYO_VALUE_TYPE_OCTAL; 162 return TOMOYO_VALUE_TYPE_OCTAL;
165 default: 163 default:
166 return TOMOYO_VALUE_TYPE_DECIMAL; 164 return TOMOYO_VALUE_TYPE_DECIMAL;
167 } 165 }
168 } 166 }
169 167
170 /** 168 /**
171 * tomoyo_print_ulong - Print an "unsigned long" value. 169 * tomoyo_print_ulong - Print an "unsigned long" value.
172 * 170 *
173 * @buffer: Pointer to buffer. 171 * @buffer: Pointer to buffer.
174 * @buffer_len: Size of @buffer. 172 * @buffer_len: Size of @buffer.
175 * @value: An "unsigned long" value. 173 * @value: An "unsigned long" value.
176 * @type: Type of @value. 174 * @type: Type of @value.
177 * 175 *
178 * Returns nothing. 176 * Returns nothing.
179 */ 177 */
180 void tomoyo_print_ulong(char *buffer, const int buffer_len, 178 void tomoyo_print_ulong(char *buffer, const int buffer_len,
181 const unsigned long value, const u8 type) 179 const unsigned long value, const u8 type)
182 { 180 {
183 if (type == TOMOYO_VALUE_TYPE_DECIMAL) 181 if (type == TOMOYO_VALUE_TYPE_DECIMAL)
184 snprintf(buffer, buffer_len, "%lu", value); 182 snprintf(buffer, buffer_len, "%lu", value);
185 else if (type == TOMOYO_VALUE_TYPE_OCTAL) 183 else if (type == TOMOYO_VALUE_TYPE_OCTAL)
186 snprintf(buffer, buffer_len, "0%lo", value); 184 snprintf(buffer, buffer_len, "0%lo", value);
187 else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL) 185 else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL)
188 snprintf(buffer, buffer_len, "0x%lX", value); 186 snprintf(buffer, buffer_len, "0x%lX", value);
189 else 187 else
190 snprintf(buffer, buffer_len, "type(%u)", type); 188 snprintf(buffer, buffer_len, "type(%u)", type);
191 } 189 }
192 190
193 /** 191 /**
194 * tomoyo_parse_name_union - Parse a tomoyo_name_union. 192 * tomoyo_parse_name_union - Parse a tomoyo_name_union.
195 * 193 *
196 * @param: Pointer to "struct tomoyo_acl_param". 194 * @param: Pointer to "struct tomoyo_acl_param".
197 * @ptr: Pointer to "struct tomoyo_name_union". 195 * @ptr: Pointer to "struct tomoyo_name_union".
198 * 196 *
199 * Returns true on success, false otherwise. 197 * Returns true on success, false otherwise.
200 */ 198 */
201 bool tomoyo_parse_name_union(struct tomoyo_acl_param *param, 199 bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
202 struct tomoyo_name_union *ptr) 200 struct tomoyo_name_union *ptr)
203 { 201 {
204 char *filename; 202 char *filename;
205 if (param->data[0] == '@') { 203 if (param->data[0] == '@') {
206 param->data++; 204 param->data++;
207 ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP); 205 ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP);
208 return ptr->group != NULL; 206 return ptr->group != NULL;
209 } 207 }
210 filename = tomoyo_read_token(param); 208 filename = tomoyo_read_token(param);
211 if (!tomoyo_correct_word(filename)) 209 if (!tomoyo_correct_word(filename))
212 return false; 210 return false;
213 ptr->filename = tomoyo_get_name(filename); 211 ptr->filename = tomoyo_get_name(filename);
214 return ptr->filename != NULL; 212 return ptr->filename != NULL;
215 } 213 }
216 214
217 /** 215 /**
218 * tomoyo_parse_number_union - Parse a tomoyo_number_union. 216 * tomoyo_parse_number_union - Parse a tomoyo_number_union.
219 * 217 *
220 * @param: Pointer to "struct tomoyo_acl_param". 218 * @param: Pointer to "struct tomoyo_acl_param".
221 * @ptr: Pointer to "struct tomoyo_number_union". 219 * @ptr: Pointer to "struct tomoyo_number_union".
222 * 220 *
223 * Returns true on success, false otherwise. 221 * Returns true on success, false otherwise.
224 */ 222 */
225 bool tomoyo_parse_number_union(struct tomoyo_acl_param *param, 223 bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
226 struct tomoyo_number_union *ptr) 224 struct tomoyo_number_union *ptr)
227 { 225 {
228 char *data; 226 char *data;
229 u8 type; 227 u8 type;
230 unsigned long v; 228 unsigned long v;
231 memset(ptr, 0, sizeof(*ptr)); 229 memset(ptr, 0, sizeof(*ptr));
232 if (param->data[0] == '@') { 230 if (param->data[0] == '@') {
233 param->data++; 231 param->data++;
234 ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP); 232 ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP);
235 return ptr->group != NULL; 233 return ptr->group != NULL;
236 } 234 }
237 data = tomoyo_read_token(param); 235 data = tomoyo_read_token(param);
238 type = tomoyo_parse_ulong(&v, &data); 236 type = tomoyo_parse_ulong(&v, &data);
239 if (type == TOMOYO_VALUE_TYPE_INVALID) 237 if (type == TOMOYO_VALUE_TYPE_INVALID)
240 return false; 238 return false;
241 ptr->values[0] = v; 239 ptr->values[0] = v;
242 ptr->value_type[0] = type; 240 ptr->value_type[0] = type;
243 if (!*data) { 241 if (!*data) {
244 ptr->values[1] = v; 242 ptr->values[1] = v;
245 ptr->value_type[1] = type; 243 ptr->value_type[1] = type;
246 return true; 244 return true;
247 } 245 }
248 if (*data++ != '-') 246 if (*data++ != '-')
249 return false; 247 return false;
250 type = tomoyo_parse_ulong(&v, &data); 248 type = tomoyo_parse_ulong(&v, &data);
251 if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v) 249 if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
252 return false; 250 return false;
253 ptr->values[1] = v; 251 ptr->values[1] = v;
254 ptr->value_type[1] = type; 252 ptr->value_type[1] = type;
255 return true; 253 return true;
256 } 254 }
257 255
258 /** 256 /**
259 * tomoyo_byte_range - Check whether the string is a \ooo style octal value. 257 * tomoyo_byte_range - Check whether the string is a \ooo style octal value.
260 * 258 *
261 * @str: Pointer to the string. 259 * @str: Pointer to the string.
262 * 260 *
263 * Returns true if @str is a \ooo style octal value, false otherwise. 261 * Returns true if @str is a \ooo style octal value, false otherwise.
264 * 262 *
265 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF. 263 * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
266 * This function verifies that \ooo is in valid range. 264 * This function verifies that \ooo is in valid range.
267 */ 265 */
268 static inline bool tomoyo_byte_range(const char *str) 266 static inline bool tomoyo_byte_range(const char *str)
269 { 267 {
270 return *str >= '0' && *str++ <= '3' && 268 return *str >= '0' && *str++ <= '3' &&
271 *str >= '0' && *str++ <= '7' && 269 *str >= '0' && *str++ <= '7' &&
272 *str >= '0' && *str <= '7'; 270 *str >= '0' && *str <= '7';
273 } 271 }
274 272
275 /** 273 /**
276 * tomoyo_alphabet_char - Check whether the character is an alphabet. 274 * tomoyo_alphabet_char - Check whether the character is an alphabet.
277 * 275 *
278 * @c: The character to check. 276 * @c: The character to check.
279 * 277 *
280 * Returns true if @c is an alphabet character, false otherwise. 278 * Returns true if @c is an alphabet character, false otherwise.
281 */ 279 */
282 static inline bool tomoyo_alphabet_char(const char c) 280 static inline bool tomoyo_alphabet_char(const char c)
283 { 281 {
284 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); 282 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
285 } 283 }
286 284
287 /** 285 /**
288 * tomoyo_make_byte - Make byte value from three octal characters. 286 * tomoyo_make_byte - Make byte value from three octal characters.
289 * 287 *
290 * @c1: The first character. 288 * @c1: The first character.
291 * @c2: The second character. 289 * @c2: The second character.
292 * @c3: The third character. 290 * @c3: The third character.
293 * 291 *
294 * Returns byte value. 292 * Returns byte value.
295 */ 293 */
296 static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3) 294 static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
297 { 295 {
298 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0'); 296 return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
299 } 297 }
300 298
301 /** 299 /**
302 * tomoyo_valid - Check whether the character is a valid char. 300 * tomoyo_valid - Check whether the character is a valid char.
303 * 301 *
304 * @c: The character to check. 302 * @c: The character to check.
305 * 303 *
306 * Returns true if @c is a valid character, false otherwise. 304 * Returns true if @c is a valid character, false otherwise.
307 */ 305 */
308 static inline bool tomoyo_valid(const unsigned char c) 306 static inline bool tomoyo_valid(const unsigned char c)
309 { 307 {
310 return c > ' ' && c < 127; 308 return c > ' ' && c < 127;
311 } 309 }
312 310
313 /** 311 /**
314 * tomoyo_invalid - Check whether the character is an invalid char. 312 * tomoyo_invalid - Check whether the character is an invalid char.
315 * 313 *
316 * @c: The character to check. 314 * @c: The character to check.
317 * 315 *
318 * Returns true if @c is an invalid character, false otherwise. 316 * Returns true if @c is an invalid character, false otherwise.
319 */ 317 */
320 static inline bool tomoyo_invalid(const unsigned char c) 318 static inline bool tomoyo_invalid(const unsigned char c)
321 { 319 {
322 return c && (c <= ' ' || c >= 127); 320 return c && (c <= ' ' || c >= 127);
323 } 321 }
324 322
325 /** 323 /**
326 * tomoyo_str_starts - Check whether the given string starts with the given keyword. 324 * tomoyo_str_starts - Check whether the given string starts with the given keyword.
327 * 325 *
328 * @src: Pointer to pointer to the string. 326 * @src: Pointer to pointer to the string.
329 * @find: Pointer to the keyword. 327 * @find: Pointer to the keyword.
330 * 328 *
331 * Returns true if @src starts with @find, false otherwise. 329 * Returns true if @src starts with @find, false otherwise.
332 * 330 *
333 * The @src is updated to point the first character after the @find 331 * The @src is updated to point the first character after the @find
334 * if @src starts with @find. 332 * if @src starts with @find.
335 */ 333 */
336 bool tomoyo_str_starts(char **src, const char *find) 334 bool tomoyo_str_starts(char **src, const char *find)
337 { 335 {
338 const int len = strlen(find); 336 const int len = strlen(find);
339 char *tmp = *src; 337 char *tmp = *src;
340 338
341 if (strncmp(tmp, find, len)) 339 if (strncmp(tmp, find, len))
342 return false; 340 return false;
343 tmp += len; 341 tmp += len;
344 *src = tmp; 342 *src = tmp;
345 return true; 343 return true;
346 } 344 }
347 345
348 /** 346 /**
349 * tomoyo_normalize_line - Format string. 347 * tomoyo_normalize_line - Format string.
350 * 348 *
351 * @buffer: The line to normalize. 349 * @buffer: The line to normalize.
352 * 350 *
353 * Leading and trailing whitespaces are removed. 351 * Leading and trailing whitespaces are removed.
354 * Multiple whitespaces are packed into single space. 352 * Multiple whitespaces are packed into single space.
355 * 353 *
356 * Returns nothing. 354 * Returns nothing.
357 */ 355 */
358 void tomoyo_normalize_line(unsigned char *buffer) 356 void tomoyo_normalize_line(unsigned char *buffer)
359 { 357 {
360 unsigned char *sp = buffer; 358 unsigned char *sp = buffer;
361 unsigned char *dp = buffer; 359 unsigned char *dp = buffer;
362 bool first = true; 360 bool first = true;
363 361
364 while (tomoyo_invalid(*sp)) 362 while (tomoyo_invalid(*sp))
365 sp++; 363 sp++;
366 while (*sp) { 364 while (*sp) {
367 if (!first) 365 if (!first)
368 *dp++ = ' '; 366 *dp++ = ' ';
369 first = false; 367 first = false;
370 while (tomoyo_valid(*sp)) 368 while (tomoyo_valid(*sp))
371 *dp++ = *sp++; 369 *dp++ = *sp++;
372 while (tomoyo_invalid(*sp)) 370 while (tomoyo_invalid(*sp))
373 sp++; 371 sp++;
374 } 372 }
375 *dp = '\0'; 373 *dp = '\0';
376 } 374 }
377 375
378 /** 376 /**
379 * tomoyo_correct_word2 - Validate a string. 377 * tomoyo_correct_word2 - Validate a string.
380 * 378 *
381 * @string: The string to check. May be non-'\0'-terminated. 379 * @string: The string to check. Maybe non-'\0'-terminated.
382 * @len: Length of @string. 380 * @len: Length of @string.
383 * 381 *
384 * Check whether the given string follows the naming rules. 382 * Check whether the given string follows the naming rules.
385 * Returns true if @string follows the naming rules, false otherwise. 383 * Returns true if @string follows the naming rules, false otherwise.
386 */ 384 */
387 static bool tomoyo_correct_word2(const char *string, size_t len) 385 static bool tomoyo_correct_word2(const char *string, size_t len)
388 { 386 {
389 const char *const start = string; 387 const char *const start = string;
390 bool in_repetition = false; 388 bool in_repetition = false;
391 unsigned char c; 389 unsigned char c;
392 unsigned char d; 390 unsigned char d;
393 unsigned char e; 391 unsigned char e;
394 if (!len) 392 if (!len)
395 goto out; 393 goto out;
396 while (len--) { 394 while (len--) {
397 c = *string++; 395 c = *string++;
398 if (c == '\\') { 396 if (c == '\\') {
399 if (!len--) 397 if (!len--)
400 goto out; 398 goto out;
401 c = *string++; 399 c = *string++;
402 switch (c) { 400 switch (c) {
403 case '\\': /* "\\" */ 401 case '\\': /* "\\" */
404 continue; 402 continue;
405 case '$': /* "\$" */ 403 case '$': /* "\$" */
406 case '+': /* "\+" */ 404 case '+': /* "\+" */
407 case '?': /* "\?" */ 405 case '?': /* "\?" */
408 case '*': /* "\*" */ 406 case '*': /* "\*" */
409 case '@': /* "\@" */ 407 case '@': /* "\@" */
410 case 'x': /* "\x" */ 408 case 'x': /* "\x" */
411 case 'X': /* "\X" */ 409 case 'X': /* "\X" */
412 case 'a': /* "\a" */ 410 case 'a': /* "\a" */
413 case 'A': /* "\A" */ 411 case 'A': /* "\A" */
414 case '-': /* "\-" */ 412 case '-': /* "\-" */
415 continue; 413 continue;
416 case '{': /* "/\{" */ 414 case '{': /* "/\{" */
417 if (string - 3 < start || *(string - 3) != '/') 415 if (string - 3 < start || *(string - 3) != '/')
418 break; 416 break;
419 in_repetition = true; 417 in_repetition = true;
420 continue; 418 continue;
421 case '}': /* "\}/" */ 419 case '}': /* "\}/" */
422 if (*string != '/') 420 if (*string != '/')
423 break; 421 break;
424 if (!in_repetition) 422 if (!in_repetition)
425 break; 423 break;
426 in_repetition = false; 424 in_repetition = false;
427 continue; 425 continue;
428 case '0': /* "\ooo" */ 426 case '0': /* "\ooo" */
429 case '1': 427 case '1':
430 case '2': 428 case '2':
431 case '3': 429 case '3':
432 if (!len-- || !len--) 430 if (!len-- || !len--)
433 break; 431 break;
434 d = *string++; 432 d = *string++;
435 e = *string++; 433 e = *string++;
436 if (d < '0' || d > '7' || e < '0' || e > '7') 434 if (d < '0' || d > '7' || e < '0' || e > '7')
437 break; 435 break;
438 c = tomoyo_make_byte(c, d, e); 436 c = tomoyo_make_byte(c, d, e);
439 if (tomoyo_invalid(c)) 437 if (tomoyo_invalid(c))
440 continue; /* pattern is not \000 */ 438 continue; /* pattern is not \000 */
441 } 439 }
442 goto out; 440 goto out;
443 } else if (in_repetition && c == '/') { 441 } else if (in_repetition && c == '/') {
444 goto out; 442 goto out;
445 } else if (tomoyo_invalid(c)) { 443 } else if (tomoyo_invalid(c)) {
446 goto out; 444 goto out;
447 } 445 }
448 } 446 }
449 if (in_repetition) 447 if (in_repetition)
450 goto out; 448 goto out;
451 return true; 449 return true;
452 out: 450 out:
453 return false; 451 return false;
454 } 452 }
455 453
456 /** 454 /**
457 * tomoyo_correct_word - Validate a string. 455 * tomoyo_correct_word - Validate a string.
458 * 456 *
459 * @string: The string to check. 457 * @string: The string to check.
460 * 458 *
461 * Check whether the given string follows the naming rules. 459 * Check whether the given string follows the naming rules.
462 * Returns true if @string follows the naming rules, false otherwise. 460 * Returns true if @string follows the naming rules, false otherwise.
463 */ 461 */
464 bool tomoyo_correct_word(const char *string) 462 bool tomoyo_correct_word(const char *string)
465 { 463 {
466 return tomoyo_correct_word2(string, strlen(string)); 464 return tomoyo_correct_word2(string, strlen(string));
467 } 465 }
468 466
469 /** 467 /**
470 * tomoyo_correct_path - Validate a pathname. 468 * tomoyo_correct_path - Validate a pathname.
471 * 469 *
472 * @filename: The pathname to check. 470 * @filename: The pathname to check.
473 * 471 *
474 * Check whether the given pathname follows the naming rules. 472 * Check whether the given pathname follows the naming rules.
475 * Returns true if @filename follows the naming rules, false otherwise. 473 * Returns true if @filename follows the naming rules, false otherwise.
476 */ 474 */
477 bool tomoyo_correct_path(const char *filename) 475 bool tomoyo_correct_path(const char *filename)
478 { 476 {
479 return *filename == '/' && tomoyo_correct_word(filename); 477 return *filename == '/' && tomoyo_correct_word(filename);
480 } 478 }
481 479
482 /** 480 /**
483 * tomoyo_correct_domain - Check whether the given domainname follows the naming rules. 481 * tomoyo_correct_domain - Check whether the given domainname follows the naming rules.
484 * 482 *
485 * @domainname: The domainname to check. 483 * @domainname: The domainname to check.
486 * 484 *
487 * Returns true if @domainname follows the naming rules, false otherwise. 485 * Returns true if @domainname follows the naming rules, false otherwise.
488 */ 486 */
489 bool tomoyo_correct_domain(const unsigned char *domainname) 487 bool tomoyo_correct_domain(const unsigned char *domainname)
490 { 488 {
491 if (!domainname || !tomoyo_domain_def(domainname)) 489 if (!domainname || !tomoyo_domain_def(domainname))
492 return false; 490 return false;
493 domainname = strchr(domainname, ' '); 491 domainname = strchr(domainname, ' ');
494 if (!domainname++) 492 if (!domainname++)
495 return true; 493 return true;
496 while (1) { 494 while (1) {
497 const unsigned char *cp = strchr(domainname, ' '); 495 const unsigned char *cp = strchr(domainname, ' ');
498 if (!cp) 496 if (!cp)
499 break; 497 break;
500 if (*domainname != '/' || 498 if (*domainname != '/' ||
501 !tomoyo_correct_word2(domainname, cp - domainname)) 499 !tomoyo_correct_word2(domainname, cp - domainname))
502 return false; 500 return false;
503 domainname = cp + 1; 501 domainname = cp + 1;
504 } 502 }
505 return tomoyo_correct_path(domainname); 503 return tomoyo_correct_path(domainname);
506 } 504 }
507 505
508 /** 506 /**
509 * tomoyo_domain_def - Check whether the given token can be a domainname. 507 * tomoyo_domain_def - Check whether the given token can be a domainname.
510 * 508 *
511 * @buffer: The token to check. 509 * @buffer: The token to check.
512 * 510 *
513 * Returns true if @buffer possibly be a domainname, false otherwise. 511 * Returns true if @buffer possibly be a domainname, false otherwise.
514 */ 512 */
515 bool tomoyo_domain_def(const unsigned char *buffer) 513 bool tomoyo_domain_def(const unsigned char *buffer)
516 { 514 {
517 const unsigned char *cp; 515 const unsigned char *cp;
518 int len; 516 int len;
519 if (*buffer != '<') 517 if (*buffer != '<')
520 return false; 518 return false;
521 cp = strchr(buffer, ' '); 519 cp = strchr(buffer, ' ');
522 if (!cp) 520 if (!cp)
523 len = strlen(buffer); 521 len = strlen(buffer);
524 else 522 else
525 len = cp - buffer; 523 len = cp - buffer;
526 if (buffer[len - 1] != '>' || 524 if (buffer[len - 1] != '>' ||
527 !tomoyo_correct_word2(buffer + 1, len - 2)) 525 !tomoyo_correct_word2(buffer + 1, len - 2))
528 return false; 526 return false;
529 return true; 527 return true;
530 } 528 }
531 529
532 /** 530 /**
533 * tomoyo_find_domain - Find a domain by the given name. 531 * tomoyo_find_domain - Find a domain by the given name.
534 * 532 *
535 * @domainname: The domainname to find. 533 * @domainname: The domainname to find.
536 * 534 *
537 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. 535 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
538 * 536 *
539 * Caller holds tomoyo_read_lock(). 537 * Caller holds tomoyo_read_lock().
540 */ 538 */
541 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 539 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
542 { 540 {
543 struct tomoyo_domain_info *domain; 541 struct tomoyo_domain_info *domain;
544 struct tomoyo_path_info name; 542 struct tomoyo_path_info name;
545 543
546 name.name = domainname; 544 name.name = domainname;
547 tomoyo_fill_path_info(&name); 545 tomoyo_fill_path_info(&name);
548 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 546 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
549 if (!domain->is_deleted && 547 if (!domain->is_deleted &&
550 !tomoyo_pathcmp(&name, domain->domainname)) 548 !tomoyo_pathcmp(&name, domain->domainname))
551 return domain; 549 return domain;
552 } 550 }
553 return NULL; 551 return NULL;
554 } 552 }
555 553
556 /** 554 /**
557 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. 555 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
558 * 556 *
559 * @filename: The string to evaluate. 557 * @filename: The string to evaluate.
560 * 558 *
561 * Returns the initial length without a pattern in @filename. 559 * Returns the initial length without a pattern in @filename.
562 */ 560 */
563 static int tomoyo_const_part_length(const char *filename) 561 static int tomoyo_const_part_length(const char *filename)
564 { 562 {
565 char c; 563 char c;
566 int len = 0; 564 int len = 0;
567 565
568 if (!filename) 566 if (!filename)
569 return 0; 567 return 0;
570 while ((c = *filename++) != '\0') { 568 while ((c = *filename++) != '\0') {
571 if (c != '\\') { 569 if (c != '\\') {
572 len++; 570 len++;
573 continue; 571 continue;
574 } 572 }
575 c = *filename++; 573 c = *filename++;
576 switch (c) { 574 switch (c) {
577 case '\\': /* "\\" */ 575 case '\\': /* "\\" */
578 len += 2; 576 len += 2;
579 continue; 577 continue;
580 case '0': /* "\ooo" */ 578 case '0': /* "\ooo" */
581 case '1': 579 case '1':
582 case '2': 580 case '2':
583 case '3': 581 case '3':
584 c = *filename++; 582 c = *filename++;
585 if (c < '0' || c > '7') 583 if (c < '0' || c > '7')
586 break; 584 break;
587 c = *filename++; 585 c = *filename++;
588 if (c < '0' || c > '7') 586 if (c < '0' || c > '7')
589 break; 587 break;
590 len += 4; 588 len += 4;
591 continue; 589 continue;
592 } 590 }
593 break; 591 break;
594 } 592 }
595 return len; 593 return len;
596 } 594 }
597 595
598 /** 596 /**
599 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members. 597 * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
600 * 598 *
601 * @ptr: Pointer to "struct tomoyo_path_info" to fill in. 599 * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
602 * 600 *
603 * The caller sets "struct tomoyo_path_info"->name. 601 * The caller sets "struct tomoyo_path_info"->name.
604 */ 602 */
605 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) 603 void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
606 { 604 {
607 const char *name = ptr->name; 605 const char *name = ptr->name;
608 const int len = strlen(name); 606 const int len = strlen(name);
609 607
610 ptr->const_len = tomoyo_const_part_length(name); 608 ptr->const_len = tomoyo_const_part_length(name);
611 ptr->is_dir = len && (name[len - 1] == '/'); 609 ptr->is_dir = len && (name[len - 1] == '/');
612 ptr->is_patterned = (ptr->const_len < len); 610 ptr->is_patterned = (ptr->const_len < len);
613 ptr->hash = full_name_hash(name, len); 611 ptr->hash = full_name_hash(name, len);
614 } 612 }
615 613
616 /** 614 /**
617 * tomoyo_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern. 615 * tomoyo_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern.
618 * 616 *
619 * @filename: The start of string to check. 617 * @filename: The start of string to check.
620 * @filename_end: The end of string to check. 618 * @filename_end: The end of string to check.
621 * @pattern: The start of pattern to compare. 619 * @pattern: The start of pattern to compare.
622 * @pattern_end: The end of pattern to compare. 620 * @pattern_end: The end of pattern to compare.
623 * 621 *
624 * Returns true if @filename matches @pattern, false otherwise. 622 * Returns true if @filename matches @pattern, false otherwise.
625 */ 623 */
626 static bool tomoyo_file_matches_pattern2(const char *filename, 624 static bool tomoyo_file_matches_pattern2(const char *filename,
627 const char *filename_end, 625 const char *filename_end,
628 const char *pattern, 626 const char *pattern,
629 const char *pattern_end) 627 const char *pattern_end)
630 { 628 {
631 while (filename < filename_end && pattern < pattern_end) { 629 while (filename < filename_end && pattern < pattern_end) {
632 char c; 630 char c;
633 if (*pattern != '\\') { 631 if (*pattern != '\\') {
634 if (*filename++ != *pattern++) 632 if (*filename++ != *pattern++)
635 return false; 633 return false;
636 continue; 634 continue;
637 } 635 }
638 c = *filename; 636 c = *filename;
639 pattern++; 637 pattern++;
640 switch (*pattern) { 638 switch (*pattern) {
641 int i; 639 int i;
642 int j; 640 int j;
643 case '?': 641 case '?':
644 if (c == '/') { 642 if (c == '/') {
645 return false; 643 return false;
646 } else if (c == '\\') { 644 } else if (c == '\\') {
647 if (filename[1] == '\\') 645 if (filename[1] == '\\')
648 filename++; 646 filename++;
649 else if (tomoyo_byte_range(filename + 1)) 647 else if (tomoyo_byte_range(filename + 1))
650 filename += 3; 648 filename += 3;
651 else 649 else
652 return false; 650 return false;
653 } 651 }
654 break; 652 break;
655 case '\\': 653 case '\\':
656 if (c != '\\') 654 if (c != '\\')
657 return false; 655 return false;
658 if (*++filename != '\\') 656 if (*++filename != '\\')
659 return false; 657 return false;
660 break; 658 break;
661 case '+': 659 case '+':
662 if (!isdigit(c)) 660 if (!isdigit(c))
663 return false; 661 return false;
664 break; 662 break;
665 case 'x': 663 case 'x':
666 if (!isxdigit(c)) 664 if (!isxdigit(c))
667 return false; 665 return false;
668 break; 666 break;
669 case 'a': 667 case 'a':
670 if (!tomoyo_alphabet_char(c)) 668 if (!tomoyo_alphabet_char(c))
671 return false; 669 return false;
672 break; 670 break;
673 case '0': 671 case '0':
674 case '1': 672 case '1':
675 case '2': 673 case '2':
676 case '3': 674 case '3':
677 if (c == '\\' && tomoyo_byte_range(filename + 1) 675 if (c == '\\' && tomoyo_byte_range(filename + 1)
678 && strncmp(filename + 1, pattern, 3) == 0) { 676 && strncmp(filename + 1, pattern, 3) == 0) {
679 filename += 3; 677 filename += 3;
680 pattern += 2; 678 pattern += 2;
681 break; 679 break;
682 } 680 }
683 return false; /* Not matched. */ 681 return false; /* Not matched. */
684 case '*': 682 case '*':
685 case '@': 683 case '@':
686 for (i = 0; i <= filename_end - filename; i++) { 684 for (i = 0; i <= filename_end - filename; i++) {
687 if (tomoyo_file_matches_pattern2( 685 if (tomoyo_file_matches_pattern2(
688 filename + i, filename_end, 686 filename + i, filename_end,
689 pattern + 1, pattern_end)) 687 pattern + 1, pattern_end))
690 return true; 688 return true;
691 c = filename[i]; 689 c = filename[i];
692 if (c == '.' && *pattern == '@') 690 if (c == '.' && *pattern == '@')
693 break; 691 break;
694 if (c != '\\') 692 if (c != '\\')
695 continue; 693 continue;
696 if (filename[i + 1] == '\\') 694 if (filename[i + 1] == '\\')
697 i++; 695 i++;
698 else if (tomoyo_byte_range(filename + i + 1)) 696 else if (tomoyo_byte_range(filename + i + 1))
699 i += 3; 697 i += 3;
700 else 698 else
701 break; /* Bad pattern. */ 699 break; /* Bad pattern. */
702 } 700 }
703 return false; /* Not matched. */ 701 return false; /* Not matched. */
704 default: 702 default:
705 j = 0; 703 j = 0;
706 c = *pattern; 704 c = *pattern;
707 if (c == '$') { 705 if (c == '$') {
708 while (isdigit(filename[j])) 706 while (isdigit(filename[j]))
709 j++; 707 j++;
710 } else if (c == 'X') { 708 } else if (c == 'X') {
711 while (isxdigit(filename[j])) 709 while (isxdigit(filename[j]))
712 j++; 710 j++;
713 } else if (c == 'A') { 711 } else if (c == 'A') {
714 while (tomoyo_alphabet_char(filename[j])) 712 while (tomoyo_alphabet_char(filename[j]))
715 j++; 713 j++;
716 } 714 }
717 for (i = 1; i <= j; i++) { 715 for (i = 1; i <= j; i++) {
718 if (tomoyo_file_matches_pattern2( 716 if (tomoyo_file_matches_pattern2(
719 filename + i, filename_end, 717 filename + i, filename_end,
720 pattern + 1, pattern_end)) 718 pattern + 1, pattern_end))
721 return true; 719 return true;
722 } 720 }
723 return false; /* Not matched or bad pattern. */ 721 return false; /* Not matched or bad pattern. */
724 } 722 }
725 filename++; 723 filename++;
726 pattern++; 724 pattern++;
727 } 725 }
728 while (*pattern == '\\' && 726 while (*pattern == '\\' &&
729 (*(pattern + 1) == '*' || *(pattern + 1) == '@')) 727 (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
730 pattern += 2; 728 pattern += 2;
731 return filename == filename_end && pattern == pattern_end; 729 return filename == filename_end && pattern == pattern_end;
732 } 730 }
733 731
734 /** 732 /**
735 * tomoyo_file_matches_pattern - Pattern matching without '/' character. 733 * tomoyo_file_matches_pattern - Pattern matching without '/' character.
736 * 734 *
737 * @filename: The start of string to check. 735 * @filename: The start of string to check.
738 * @filename_end: The end of string to check. 736 * @filename_end: The end of string to check.
739 * @pattern: The start of pattern to compare. 737 * @pattern: The start of pattern to compare.
740 * @pattern_end: The end of pattern to compare. 738 * @pattern_end: The end of pattern to compare.
741 * 739 *
742 * Returns true if @filename matches @pattern, false otherwise. 740 * Returns true if @filename matches @pattern, false otherwise.
743 */ 741 */
744 static bool tomoyo_file_matches_pattern(const char *filename, 742 static bool tomoyo_file_matches_pattern(const char *filename,
745 const char *filename_end, 743 const char *filename_end,
746 const char *pattern, 744 const char *pattern,
747 const char *pattern_end) 745 const char *pattern_end)
748 { 746 {
749 const char *pattern_start = pattern; 747 const char *pattern_start = pattern;
750 bool first = true; 748 bool first = true;
751 bool result; 749 bool result;
752 750
753 while (pattern < pattern_end - 1) { 751 while (pattern < pattern_end - 1) {
754 /* Split at "\-" pattern. */ 752 /* Split at "\-" pattern. */
755 if (*pattern++ != '\\' || *pattern++ != '-') 753 if (*pattern++ != '\\' || *pattern++ != '-')
756 continue; 754 continue;
757 result = tomoyo_file_matches_pattern2(filename, 755 result = tomoyo_file_matches_pattern2(filename,
758 filename_end, 756 filename_end,
759 pattern_start, 757 pattern_start,
760 pattern - 2); 758 pattern - 2);
761 if (first) 759 if (first)
762 result = !result; 760 result = !result;
763 if (result) 761 if (result)
764 return false; 762 return false;
765 first = false; 763 first = false;
766 pattern_start = pattern; 764 pattern_start = pattern;
767 } 765 }
768 result = tomoyo_file_matches_pattern2(filename, filename_end, 766 result = tomoyo_file_matches_pattern2(filename, filename_end,
769 pattern_start, pattern_end); 767 pattern_start, pattern_end);
770 return first ? result : !result; 768 return first ? result : !result;
771 } 769 }
772 770
773 /** 771 /**
774 * tomoyo_path_matches_pattern2 - Do pathname pattern matching. 772 * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
775 * 773 *
776 * @f: The start of string to check. 774 * @f: The start of string to check.
777 * @p: The start of pattern to compare. 775 * @p: The start of pattern to compare.
778 * 776 *
779 * Returns true if @f matches @p, false otherwise. 777 * Returns true if @f matches @p, false otherwise.
780 */ 778 */
781 static bool tomoyo_path_matches_pattern2(const char *f, const char *p) 779 static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
782 { 780 {
783 const char *f_delimiter; 781 const char *f_delimiter;
784 const char *p_delimiter; 782 const char *p_delimiter;
785 783
786 while (*f && *p) { 784 while (*f && *p) {
787 f_delimiter = strchr(f, '/'); 785 f_delimiter = strchr(f, '/');
788 if (!f_delimiter) 786 if (!f_delimiter)
789 f_delimiter = f + strlen(f); 787 f_delimiter = f + strlen(f);
790 p_delimiter = strchr(p, '/'); 788 p_delimiter = strchr(p, '/');
791 if (!p_delimiter) 789 if (!p_delimiter)
792 p_delimiter = p + strlen(p); 790 p_delimiter = p + strlen(p);
793 if (*p == '\\' && *(p + 1) == '{') 791 if (*p == '\\' && *(p + 1) == '{')
794 goto recursive; 792 goto recursive;
795 if (!tomoyo_file_matches_pattern(f, f_delimiter, p, 793 if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
796 p_delimiter)) 794 p_delimiter))
797 return false; 795 return false;
798 f = f_delimiter; 796 f = f_delimiter;
799 if (*f) 797 if (*f)
800 f++; 798 f++;
801 p = p_delimiter; 799 p = p_delimiter;
802 if (*p) 800 if (*p)
803 p++; 801 p++;
804 } 802 }
805 /* Ignore trailing "\*" and "\@" in @pattern. */ 803 /* Ignore trailing "\*" and "\@" in @pattern. */
806 while (*p == '\\' && 804 while (*p == '\\' &&
807 (*(p + 1) == '*' || *(p + 1) == '@')) 805 (*(p + 1) == '*' || *(p + 1) == '@'))
808 p += 2; 806 p += 2;
809 return !*f && !*p; 807 return !*f && !*p;
810 recursive: 808 recursive:
811 /* 809 /*
812 * The "\{" pattern is permitted only after '/' character. 810 * The "\{" pattern is permitted only after '/' character.
813 * This guarantees that below "*(p - 1)" is safe. 811 * This guarantees that below "*(p - 1)" is safe.
814 * Also, the "\}" pattern is permitted only before '/' character 812 * Also, the "\}" pattern is permitted only before '/' character
815 * so that "\{" + "\}" pair will not break the "\-" operator. 813 * so that "\{" + "\}" pair will not break the "\-" operator.
816 */ 814 */
817 if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' || 815 if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
818 *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\') 816 *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
819 return false; /* Bad pattern. */ 817 return false; /* Bad pattern. */
820 do { 818 do {
821 /* Compare current component with pattern. */ 819 /* Compare current component with pattern. */
822 if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2, 820 if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
823 p_delimiter - 2)) 821 p_delimiter - 2))
824 break; 822 break;
825 /* Proceed to next component. */ 823 /* Proceed to next component. */
826 f = f_delimiter; 824 f = f_delimiter;
827 if (!*f) 825 if (!*f)
828 break; 826 break;
829 f++; 827 f++;
830 /* Continue comparison. */ 828 /* Continue comparison. */
831 if (tomoyo_path_matches_pattern2(f, p_delimiter + 1)) 829 if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
832 return true; 830 return true;
833 f_delimiter = strchr(f, '/'); 831 f_delimiter = strchr(f, '/');
834 } while (f_delimiter); 832 } while (f_delimiter);
835 return false; /* Not matched. */ 833 return false; /* Not matched. */
836 } 834 }
837 835
838 /** 836 /**
839 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. 837 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
840 * 838 *
841 * @filename: The filename to check. 839 * @filename: The filename to check.
842 * @pattern: The pattern to compare. 840 * @pattern: The pattern to compare.
843 * 841 *
844 * Returns true if matches, false otherwise. 842 * Returns true if matches, false otherwise.
845 * 843 *
846 * The following patterns are available. 844 * The following patterns are available.
847 * \\ \ itself. 845 * \\ \ itself.
848 * \ooo Octal representation of a byte. 846 * \ooo Octal representation of a byte.
849 * \* Zero or more repetitions of characters other than '/'. 847 * \* Zero or more repetitions of characters other than '/'.
850 * \@ Zero or more repetitions of characters other than '/' or '.'. 848 * \@ Zero or more repetitions of characters other than '/' or '.'.
851 * \? 1 byte character other than '/'. 849 * \? 1 byte character other than '/'.
852 * \$ One or more repetitions of decimal digits. 850 * \$ One or more repetitions of decimal digits.
853 * \+ 1 decimal digit. 851 * \+ 1 decimal digit.
854 * \X One or more repetitions of hexadecimal digits. 852 * \X One or more repetitions of hexadecimal digits.
855 * \x 1 hexadecimal digit. 853 * \x 1 hexadecimal digit.
856 * \A One or more repetitions of alphabet characters. 854 * \A One or more repetitions of alphabet characters.
857 * \a 1 alphabet character. 855 * \a 1 alphabet character.
858 * 856 *
859 * \- Subtraction operator. 857 * \- Subtraction operator.
860 * 858 *
861 * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/ 859 * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
862 * /dir/dir/dir/ ). 860 * /dir/dir/dir/ ).
863 */ 861 */
864 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 862 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
865 const struct tomoyo_path_info *pattern) 863 const struct tomoyo_path_info *pattern)
866 { 864 {
867 const char *f = filename->name; 865 const char *f = filename->name;
868 const char *p = pattern->name; 866 const char *p = pattern->name;
869 const int len = pattern->const_len; 867 const int len = pattern->const_len;
870 868
871 /* If @pattern doesn't contain pattern, I can use strcmp(). */ 869 /* If @pattern doesn't contain pattern, I can use strcmp(). */
872 if (!pattern->is_patterned) 870 if (!pattern->is_patterned)
873 return !tomoyo_pathcmp(filename, pattern); 871 return !tomoyo_pathcmp(filename, pattern);
874 /* Don't compare directory and non-directory. */ 872 /* Don't compare directory and non-directory. */
875 if (filename->is_dir != pattern->is_dir) 873 if (filename->is_dir != pattern->is_dir)
876 return false; 874 return false;
877 /* Compare the initial length without patterns. */ 875 /* Compare the initial length without patterns. */
878 if (strncmp(f, p, len)) 876 if (strncmp(f, p, len))
879 return false; 877 return false;
880 f += len; 878 f += len;
881 p += len; 879 p += len;
882 return tomoyo_path_matches_pattern2(f, p); 880 return tomoyo_path_matches_pattern2(f, p);
883 } 881 }
884 882
885 /** 883 /**
886 * tomoyo_get_exe - Get tomoyo_realpath() of current process. 884 * tomoyo_get_exe - Get tomoyo_realpath() of current process.
887 * 885 *
888 * Returns the tomoyo_realpath() of current process on success, NULL otherwise. 886 * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
889 * 887 *
890 * This function uses kzalloc(), so the caller must call kfree() 888 * This function uses kzalloc(), so the caller must call kfree()
891 * if this function didn't return NULL. 889 * if this function didn't return NULL.
892 */ 890 */
893 const char *tomoyo_get_exe(void) 891 const char *tomoyo_get_exe(void)
894 { 892 {
895 struct mm_struct *mm = current->mm; 893 struct mm_struct *mm = current->mm;
896 struct vm_area_struct *vma; 894 struct vm_area_struct *vma;
897 const char *cp = NULL; 895 const char *cp = NULL;
898 896
899 if (!mm) 897 if (!mm)
900 return NULL; 898 return NULL;
901 down_read(&mm->mmap_sem); 899 down_read(&mm->mmap_sem);
902 for (vma = mm->mmap; vma; vma = vma->vm_next) { 900 for (vma = mm->mmap; vma; vma = vma->vm_next) {
903 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { 901 if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
904 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path); 902 cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
905 break; 903 break;
906 } 904 }
907 } 905 }
908 up_read(&mm->mmap_sem); 906 up_read(&mm->mmap_sem);
909 return cp; 907 return cp;
910 } 908 }
911 909
912 /** 910 /**
913 * tomoyo_get_mode - Get MAC mode. 911 * tomoyo_get_mode - Get MAC mode.
914 * 912 *
915 * @ns: Pointer to "struct tomoyo_policy_namespace". 913 * @ns: Pointer to "struct tomoyo_policy_namespace".
916 * @profile: Profile number. 914 * @profile: Profile number.
917 * @index: Index number of functionality. 915 * @index: Index number of functionality.
918 * 916 *
919 * Returns mode. 917 * Returns mode.
920 */ 918 */
921 int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile, 919 int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
922 const u8 index) 920 const u8 index)
923 { 921 {
924 u8 mode; 922 u8 mode;
925 const u8 category = TOMOYO_MAC_CATEGORY_FILE; 923 const u8 category = TOMOYO_MAC_CATEGORY_FILE;
926 if (!tomoyo_policy_loaded) 924 if (!tomoyo_policy_loaded)
927 return TOMOYO_CONFIG_DISABLED; 925 return TOMOYO_CONFIG_DISABLED;
928 mode = tomoyo_profile(ns, profile)->config[index]; 926 mode = tomoyo_profile(ns, profile)->config[index];
929 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 927 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
930 mode = tomoyo_profile(ns, profile)->config[category]; 928 mode = tomoyo_profile(ns, profile)->config[category];
931 if (mode == TOMOYO_CONFIG_USE_DEFAULT) 929 if (mode == TOMOYO_CONFIG_USE_DEFAULT)
932 mode = tomoyo_profile(ns, profile)->default_config; 930 mode = tomoyo_profile(ns, profile)->default_config;
933 return mode & 3; 931 return mode & 3;
934 } 932 }
935 933
936 /** 934 /**
937 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members. 935 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
938 * 936 *
939 * @r: Pointer to "struct tomoyo_request_info" to initialize. 937 * @r: Pointer to "struct tomoyo_request_info" to initialize.
940 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain(). 938 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
941 * @index: Index number of functionality. 939 * @index: Index number of functionality.
942 * 940 *
943 * Returns mode. 941 * Returns mode.
944 */ 942 */
945 int tomoyo_init_request_info(struct tomoyo_request_info *r, 943 int tomoyo_init_request_info(struct tomoyo_request_info *r,
946 struct tomoyo_domain_info *domain, const u8 index) 944 struct tomoyo_domain_info *domain, const u8 index)
947 { 945 {
948 u8 profile; 946 u8 profile;
949 memset(r, 0, sizeof(*r)); 947 memset(r, 0, sizeof(*r));
950 if (!domain) 948 if (!domain)
951 domain = tomoyo_domain(); 949 domain = tomoyo_domain();
952 r->domain = domain; 950 r->domain = domain;
953 profile = domain->profile; 951 profile = domain->profile;
954 r->profile = profile; 952 r->profile = profile;
955 r->type = index; 953 r->type = index;
956 r->mode = tomoyo_get_mode(domain->ns, profile, index); 954 r->mode = tomoyo_get_mode(domain->ns, profile, index);
957 return r->mode; 955 return r->mode;
958 } 956 }
959 957
960 /** 958 /**
961 * tomoyo_domain_quota_is_ok - Check for domain's quota. 959 * tomoyo_domain_quota_is_ok - Check for domain's quota.
962 * 960 *
963 * @r: Pointer to "struct tomoyo_request_info". 961 * @r: Pointer to "struct tomoyo_request_info".
964 * 962 *
965 * Returns true if the domain is not exceeded quota, false otherwise. 963 * Returns true if the domain is not exceeded quota, false otherwise.
966 * 964 *
967 * Caller holds tomoyo_read_lock(). 965 * Caller holds tomoyo_read_lock().
968 */ 966 */
969 bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r) 967 bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
970 { 968 {
971 unsigned int count = 0; 969 unsigned int count = 0;
972 struct tomoyo_domain_info *domain = r->domain; 970 struct tomoyo_domain_info *domain = r->domain;
973 struct tomoyo_acl_info *ptr; 971 struct tomoyo_acl_info *ptr;
974 972
975 if (r->mode != TOMOYO_CONFIG_LEARNING) 973 if (r->mode != TOMOYO_CONFIG_LEARNING)
976 return false; 974 return false;
977 if (!domain) 975 if (!domain)
978 return true; 976 return true;
979 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 977 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
980 u16 perm; 978 u16 perm;
981 u8 i; 979 u8 i;
982 if (ptr->is_deleted) 980 if (ptr->is_deleted)
983 continue; 981 continue;
984 switch (ptr->type) { 982 switch (ptr->type) {
985 case TOMOYO_TYPE_PATH_ACL: 983 case TOMOYO_TYPE_PATH_ACL:
986 perm = container_of(ptr, struct tomoyo_path_acl, head) 984 perm = container_of(ptr, struct tomoyo_path_acl, head)
987 ->perm; 985 ->perm;
988 break; 986 break;
989 case TOMOYO_TYPE_PATH2_ACL: 987 case TOMOYO_TYPE_PATH2_ACL:
990 perm = container_of(ptr, struct tomoyo_path2_acl, head) 988 perm = container_of(ptr, struct tomoyo_path2_acl, head)
991 ->perm; 989 ->perm;
992 break; 990 break;
993 case TOMOYO_TYPE_PATH_NUMBER_ACL: 991 case TOMOYO_TYPE_PATH_NUMBER_ACL:
994 perm = container_of(ptr, struct tomoyo_path_number_acl, 992 perm = container_of(ptr, struct tomoyo_path_number_acl,
995 head)->perm; 993 head)->perm;
996 break; 994 break;
997 case TOMOYO_TYPE_MKDEV_ACL: 995 case TOMOYO_TYPE_MKDEV_ACL:
998 perm = container_of(ptr, struct tomoyo_mkdev_acl, 996 perm = container_of(ptr, struct tomoyo_mkdev_acl,
999 head)->perm; 997 head)->perm;
1000 break; 998 break;
1001 default: 999 default:
1002 perm = 1; 1000 perm = 1;
1003 } 1001 }
1004 for (i = 0; i < 16; i++) 1002 for (i = 0; i < 16; i++)
1005 if (perm & (1 << i)) 1003 if (perm & (1 << i))
1006 count++; 1004 count++;
1007 } 1005 }
1008 if (count < tomoyo_profile(domain->ns, domain->profile)-> 1006 if (count < tomoyo_profile(domain->ns, domain->profile)->
1009 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY]) 1007 pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
1010 return true; 1008 return true;
1011 if (!domain->flags[TOMOYO_DIF_QUOTA_WARNED]) { 1009 if (!domain->flags[TOMOYO_DIF_QUOTA_WARNED]) {
1012 domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true; 1010 domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true;
1013 /* r->granted = false; */ 1011 /* r->granted = false; */
1014 tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]); 1012 tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
1015 printk(KERN_WARNING "WARNING: " 1013 printk(KERN_WARNING "WARNING: "
1016 "Domain '%s' has too many ACLs to hold. " 1014 "Domain '%s' has too many ACLs to hold. "
1017 "Stopped learning mode.\n", domain->domainname->name); 1015 "Stopped learning mode.\n", domain->domainname->name);
1018 } 1016 }
1019 return false; 1017 return false;
1020 } 1018 }
1021 1019