~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/tomoyo/common.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * security/tomoyo/common.c
  4  *
  5  * Copyright (C) 2005-2011  NTT DATA CORPORATION
  6  */
  7 
  8 #include <linux/uaccess.h>
  9 #include <linux/slab.h>
 10 #include <linux/security.h>
 11 #include <linux/string_helpers.h>
 12 #include "common.h"
 13 
 14 /* String table for operation mode. */
 15 const char * const tomoyo_mode[TOMOYO_CONFIG_MAX_MODE] = {
 16         [TOMOYO_CONFIG_DISABLED]   = "disabled",
 17         [TOMOYO_CONFIG_LEARNING]   = "learning",
 18         [TOMOYO_CONFIG_PERMISSIVE] = "permissive",
 19         [TOMOYO_CONFIG_ENFORCING]  = "enforcing"
 20 };
 21 
 22 /* String table for /sys/kernel/security/tomoyo/profile */
 23 const char * const tomoyo_mac_keywords[TOMOYO_MAX_MAC_INDEX
 24                                        + TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
 25         /* CONFIG::file group */
 26         [TOMOYO_MAC_FILE_EXECUTE]    = "execute",
 27         [TOMOYO_MAC_FILE_OPEN]       = "open",
 28         [TOMOYO_MAC_FILE_CREATE]     = "create",
 29         [TOMOYO_MAC_FILE_UNLINK]     = "unlink",
 30         [TOMOYO_MAC_FILE_GETATTR]    = "getattr",
 31         [TOMOYO_MAC_FILE_MKDIR]      = "mkdir",
 32         [TOMOYO_MAC_FILE_RMDIR]      = "rmdir",
 33         [TOMOYO_MAC_FILE_MKFIFO]     = "mkfifo",
 34         [TOMOYO_MAC_FILE_MKSOCK]     = "mksock",
 35         [TOMOYO_MAC_FILE_TRUNCATE]   = "truncate",
 36         [TOMOYO_MAC_FILE_SYMLINK]    = "symlink",
 37         [TOMOYO_MAC_FILE_MKBLOCK]    = "mkblock",
 38         [TOMOYO_MAC_FILE_MKCHAR]     = "mkchar",
 39         [TOMOYO_MAC_FILE_LINK]       = "link",
 40         [TOMOYO_MAC_FILE_RENAME]     = "rename",
 41         [TOMOYO_MAC_FILE_CHMOD]      = "chmod",
 42         [TOMOYO_MAC_FILE_CHOWN]      = "chown",
 43         [TOMOYO_MAC_FILE_CHGRP]      = "chgrp",
 44         [TOMOYO_MAC_FILE_IOCTL]      = "ioctl",
 45         [TOMOYO_MAC_FILE_CHROOT]     = "chroot",
 46         [TOMOYO_MAC_FILE_MOUNT]      = "mount",
 47         [TOMOYO_MAC_FILE_UMOUNT]     = "unmount",
 48         [TOMOYO_MAC_FILE_PIVOT_ROOT] = "pivot_root",
 49         /* CONFIG::network group */
 50         [TOMOYO_MAC_NETWORK_INET_STREAM_BIND]       = "inet_stream_bind",
 51         [TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN]     = "inet_stream_listen",
 52         [TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT]    = "inet_stream_connect",
 53         [TOMOYO_MAC_NETWORK_INET_DGRAM_BIND]        = "inet_dgram_bind",
 54         [TOMOYO_MAC_NETWORK_INET_DGRAM_SEND]        = "inet_dgram_send",
 55         [TOMOYO_MAC_NETWORK_INET_RAW_BIND]          = "inet_raw_bind",
 56         [TOMOYO_MAC_NETWORK_INET_RAW_SEND]          = "inet_raw_send",
 57         [TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND]       = "unix_stream_bind",
 58         [TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN]     = "unix_stream_listen",
 59         [TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT]    = "unix_stream_connect",
 60         [TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND]        = "unix_dgram_bind",
 61         [TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND]        = "unix_dgram_send",
 62         [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = "unix_seqpacket_bind",
 63         [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = "unix_seqpacket_listen",
 64         [TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
 65         /* CONFIG::misc group */
 66         [TOMOYO_MAC_ENVIRON] = "env",
 67         /* CONFIG group */
 68         [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_FILE] = "file",
 69         [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_NETWORK] = "network",
 70         [TOMOYO_MAX_MAC_INDEX + TOMOYO_MAC_CATEGORY_MISC] = "misc",
 71 };
 72 
 73 /* String table for conditions. */
 74 const char * const tomoyo_condition_keyword[TOMOYO_MAX_CONDITION_KEYWORD] = {
 75         [TOMOYO_TASK_UID]             = "task.uid",
 76         [TOMOYO_TASK_EUID]            = "task.euid",
 77         [TOMOYO_TASK_SUID]            = "task.suid",
 78         [TOMOYO_TASK_FSUID]           = "task.fsuid",
 79         [TOMOYO_TASK_GID]             = "task.gid",
 80         [TOMOYO_TASK_EGID]            = "task.egid",
 81         [TOMOYO_TASK_SGID]            = "task.sgid",
 82         [TOMOYO_TASK_FSGID]           = "task.fsgid",
 83         [TOMOYO_TASK_PID]             = "task.pid",
 84         [TOMOYO_TASK_PPID]            = "task.ppid",
 85         [TOMOYO_EXEC_ARGC]            = "exec.argc",
 86         [TOMOYO_EXEC_ENVC]            = "exec.envc",
 87         [TOMOYO_TYPE_IS_SOCKET]       = "socket",
 88         [TOMOYO_TYPE_IS_SYMLINK]      = "symlink",
 89         [TOMOYO_TYPE_IS_FILE]         = "file",
 90         [TOMOYO_TYPE_IS_BLOCK_DEV]    = "block",
 91         [TOMOYO_TYPE_IS_DIRECTORY]    = "directory",
 92         [TOMOYO_TYPE_IS_CHAR_DEV]     = "char",
 93         [TOMOYO_TYPE_IS_FIFO]         = "fifo",
 94         [TOMOYO_MODE_SETUID]          = "setuid",
 95         [TOMOYO_MODE_SETGID]          = "setgid",
 96         [TOMOYO_MODE_STICKY]          = "sticky",
 97         [TOMOYO_MODE_OWNER_READ]      = "owner_read",
 98         [TOMOYO_MODE_OWNER_WRITE]     = "owner_write",
 99         [TOMOYO_MODE_OWNER_EXECUTE]   = "owner_execute",
100         [TOMOYO_MODE_GROUP_READ]      = "group_read",
101         [TOMOYO_MODE_GROUP_WRITE]     = "group_write",
102         [TOMOYO_MODE_GROUP_EXECUTE]   = "group_execute",
103         [TOMOYO_MODE_OTHERS_READ]     = "others_read",
104         [TOMOYO_MODE_OTHERS_WRITE]    = "others_write",
105         [TOMOYO_MODE_OTHERS_EXECUTE]  = "others_execute",
106         [TOMOYO_EXEC_REALPATH]        = "exec.realpath",
107         [TOMOYO_SYMLINK_TARGET]       = "symlink.target",
108         [TOMOYO_PATH1_UID]            = "path1.uid",
109         [TOMOYO_PATH1_GID]            = "path1.gid",
110         [TOMOYO_PATH1_INO]            = "path1.ino",
111         [TOMOYO_PATH1_MAJOR]          = "path1.major",
112         [TOMOYO_PATH1_MINOR]          = "path1.minor",
113         [TOMOYO_PATH1_PERM]           = "path1.perm",
114         [TOMOYO_PATH1_TYPE]           = "path1.type",
115         [TOMOYO_PATH1_DEV_MAJOR]      = "path1.dev_major",
116         [TOMOYO_PATH1_DEV_MINOR]      = "path1.dev_minor",
117         [TOMOYO_PATH2_UID]            = "path2.uid",
118         [TOMOYO_PATH2_GID]            = "path2.gid",
119         [TOMOYO_PATH2_INO]            = "path2.ino",
120         [TOMOYO_PATH2_MAJOR]          = "path2.major",
121         [TOMOYO_PATH2_MINOR]          = "path2.minor",
122         [TOMOYO_PATH2_PERM]           = "path2.perm",
123         [TOMOYO_PATH2_TYPE]           = "path2.type",
124         [TOMOYO_PATH2_DEV_MAJOR]      = "path2.dev_major",
125         [TOMOYO_PATH2_DEV_MINOR]      = "path2.dev_minor",
126         [TOMOYO_PATH1_PARENT_UID]     = "path1.parent.uid",
127         [TOMOYO_PATH1_PARENT_GID]     = "path1.parent.gid",
128         [TOMOYO_PATH1_PARENT_INO]     = "path1.parent.ino",
129         [TOMOYO_PATH1_PARENT_PERM]    = "path1.parent.perm",
130         [TOMOYO_PATH2_PARENT_UID]     = "path2.parent.uid",
131         [TOMOYO_PATH2_PARENT_GID]     = "path2.parent.gid",
132         [TOMOYO_PATH2_PARENT_INO]     = "path2.parent.ino",
133         [TOMOYO_PATH2_PARENT_PERM]    = "path2.parent.perm",
134 };
135 
136 /* String table for PREFERENCE keyword. */
137 static const char * const tomoyo_pref_keywords[TOMOYO_MAX_PREF] = {
138         [TOMOYO_PREF_MAX_AUDIT_LOG]      = "max_audit_log",
139         [TOMOYO_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry",
140 };
141 
142 /* String table for path operation. */
143 const char * const tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
144         [TOMOYO_TYPE_EXECUTE]    = "execute",
145         [TOMOYO_TYPE_READ]       = "read",
146         [TOMOYO_TYPE_WRITE]      = "write",
147         [TOMOYO_TYPE_APPEND]     = "append",
148         [TOMOYO_TYPE_UNLINK]     = "unlink",
149         [TOMOYO_TYPE_GETATTR]    = "getattr",
150         [TOMOYO_TYPE_RMDIR]      = "rmdir",
151         [TOMOYO_TYPE_TRUNCATE]   = "truncate",
152         [TOMOYO_TYPE_SYMLINK]    = "symlink",
153         [TOMOYO_TYPE_CHROOT]     = "chroot",
154         [TOMOYO_TYPE_UMOUNT]     = "unmount",
155 };
156 
157 /* String table for socket's operation. */
158 const char * const tomoyo_socket_keyword[TOMOYO_MAX_NETWORK_OPERATION] = {
159         [TOMOYO_NETWORK_BIND]    = "bind",
160         [TOMOYO_NETWORK_LISTEN]  = "listen",
161         [TOMOYO_NETWORK_CONNECT] = "connect",
162         [TOMOYO_NETWORK_SEND]    = "send",
163 };
164 
165 /* String table for categories. */
166 static const char * const tomoyo_category_keywords
167 [TOMOYO_MAX_MAC_CATEGORY_INDEX] = {
168         [TOMOYO_MAC_CATEGORY_FILE]    = "file",
169         [TOMOYO_MAC_CATEGORY_NETWORK] = "network",
170         [TOMOYO_MAC_CATEGORY_MISC]    = "misc",
171 };
172 
173 /* Permit policy management by non-root user? */
174 static bool tomoyo_manage_by_non_root;
175 
176 /* Utility functions. */
177 
178 /**
179  * tomoyo_addprintf - strncat()-like-snprintf().
180  *
181  * @buffer: Buffer to write to. Must be '\0'-terminated.
182  * @len:    Size of @buffer.
183  * @fmt:    The printf()'s format string, followed by parameters.
184  *
185  * Returns nothing.
186  */
187 __printf(3, 4)
188 static void tomoyo_addprintf(char *buffer, int len, const char *fmt, ...)
189 {
190         va_list args;
191         const int pos = strlen(buffer);
192 
193         va_start(args, fmt);
194         vsnprintf(buffer + pos, len - pos - 1, fmt, args);
195         va_end(args);
196 }
197 
198 /**
199  * tomoyo_flush - Flush queued string to userspace's buffer.
200  *
201  * @head:   Pointer to "struct tomoyo_io_buffer".
202  *
203  * Returns true if all data was flushed, false otherwise.
204  */
205 static bool tomoyo_flush(struct tomoyo_io_buffer *head)
206 {
207         while (head->r.w_pos) {
208                 const char *w = head->r.w[0];
209                 size_t len = strlen(w);
210 
211                 if (len) {
212                         if (len > head->read_user_buf_avail)
213                                 len = head->read_user_buf_avail;
214                         if (!len)
215                                 return false;
216                         if (copy_to_user(head->read_user_buf, w, len))
217                                 return false;
218                         head->read_user_buf_avail -= len;
219                         head->read_user_buf += len;
220                         w += len;
221                 }
222                 head->r.w[0] = w;
223                 if (*w)
224                         return false;
225                 /* Add '\0' for audit logs and query. */
226                 if (head->poll) {
227                         if (!head->read_user_buf_avail ||
228                             copy_to_user(head->read_user_buf, "", 1))
229                                 return false;
230                         head->read_user_buf_avail--;
231                         head->read_user_buf++;
232                 }
233                 head->r.w_pos--;
234                 for (len = 0; len < head->r.w_pos; len++)
235                         head->r.w[len] = head->r.w[len + 1];
236         }
237         head->r.avail = 0;
238         return true;
239 }
240 
241 /**
242  * tomoyo_set_string - Queue string to "struct tomoyo_io_buffer" structure.
243  *
244  * @head:   Pointer to "struct tomoyo_io_buffer".
245  * @string: String to print.
246  *
247  * Note that @string has to be kept valid until @head is kfree()d.
248  * This means that char[] allocated on stack memory cannot be passed to
249  * this function. Use tomoyo_io_printf() for char[] allocated on stack memory.
250  */
251 static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
252 {
253         if (head->r.w_pos < TOMOYO_MAX_IO_READ_QUEUE) {
254                 head->r.w[head->r.w_pos++] = string;
255                 tomoyo_flush(head);
256         } else
257                 WARN_ON(1);
258 }
259 
260 static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
261                              ...) __printf(2, 3);
262 
263 /**
264  * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
265  *
266  * @head: Pointer to "struct tomoyo_io_buffer".
267  * @fmt:  The printf()'s format string, followed by parameters.
268  */
269 static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
270                              ...)
271 {
272         va_list args;
273         size_t len;
274         size_t pos = head->r.avail;
275         int size = head->readbuf_size - pos;
276 
277         if (size <= 0)
278                 return;
279         va_start(args, fmt);
280         len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1;
281         va_end(args);
282         if (pos + len >= head->readbuf_size) {
283                 WARN_ON(1);
284                 return;
285         }
286         head->r.avail += len;
287         tomoyo_set_string(head, head->read_buf + pos);
288 }
289 
290 /**
291  * tomoyo_set_space - Put a space to "struct tomoyo_io_buffer" structure.
292  *
293  * @head: Pointer to "struct tomoyo_io_buffer".
294  *
295  * Returns nothing.
296  */
297 static void tomoyo_set_space(struct tomoyo_io_buffer *head)
298 {
299         tomoyo_set_string(head, " ");
300 }
301 
302 /**
303  * tomoyo_set_lf - Put a line feed to "struct tomoyo_io_buffer" structure.
304  *
305  * @head: Pointer to "struct tomoyo_io_buffer".
306  *
307  * Returns nothing.
308  */
309 static bool tomoyo_set_lf(struct tomoyo_io_buffer *head)
310 {
311         tomoyo_set_string(head, "\n");
312         return !head->r.w_pos;
313 }
314 
315 /**
316  * tomoyo_set_slash - Put a shash to "struct tomoyo_io_buffer" structure.
317  *
318  * @head: Pointer to "struct tomoyo_io_buffer".
319  *
320  * Returns nothing.
321  */
322 static void tomoyo_set_slash(struct tomoyo_io_buffer *head)
323 {
324         tomoyo_set_string(head, "/");
325 }
326 
327 /* List of namespaces. */
328 LIST_HEAD(tomoyo_namespace_list);
329 /* True if namespace other than tomoyo_kernel_namespace is defined. */
330 static bool tomoyo_namespace_enabled;
331 
332 /**
333  * tomoyo_init_policy_namespace - Initialize namespace.
334  *
335  * @ns: Pointer to "struct tomoyo_policy_namespace".
336  *
337  * Returns nothing.
338  */
339 void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns)
340 {
341         unsigned int idx;
342 
343         for (idx = 0; idx < TOMOYO_MAX_ACL_GROUPS; idx++)
344                 INIT_LIST_HEAD(&ns->acl_group[idx]);
345         for (idx = 0; idx < TOMOYO_MAX_GROUP; idx++)
346                 INIT_LIST_HEAD(&ns->group_list[idx]);
347         for (idx = 0; idx < TOMOYO_MAX_POLICY; idx++)
348                 INIT_LIST_HEAD(&ns->policy_list[idx]);
349         ns->profile_version = 20150505;
350         tomoyo_namespace_enabled = !list_empty(&tomoyo_namespace_list);
351         list_add_tail_rcu(&ns->namespace_list, &tomoyo_namespace_list);
352 }
353 
354 /**
355  * tomoyo_print_namespace - Print namespace header.
356  *
357  * @head: Pointer to "struct tomoyo_io_buffer".
358  *
359  * Returns nothing.
360  */
361 static void tomoyo_print_namespace(struct tomoyo_io_buffer *head)
362 {
363         if (!tomoyo_namespace_enabled)
364                 return;
365         tomoyo_set_string(head,
366                           container_of(head->r.ns,
367                                        struct tomoyo_policy_namespace,
368                                        namespace_list)->name);
369         tomoyo_set_space(head);
370 }
371 
372 /**
373  * tomoyo_print_name_union - Print a tomoyo_name_union.
374  *
375  * @head: Pointer to "struct tomoyo_io_buffer".
376  * @ptr:  Pointer to "struct tomoyo_name_union".
377  */
378 static void tomoyo_print_name_union(struct tomoyo_io_buffer *head,
379                                     const struct tomoyo_name_union *ptr)
380 {
381         tomoyo_set_space(head);
382         if (ptr->group) {
383                 tomoyo_set_string(head, "@");
384                 tomoyo_set_string(head, ptr->group->group_name->name);
385         } else {
386                 tomoyo_set_string(head, ptr->filename->name);
387         }
388 }
389 
390 /**
391  * tomoyo_print_name_union_quoted - Print a tomoyo_name_union with a quote.
392  *
393  * @head: Pointer to "struct tomoyo_io_buffer".
394  * @ptr:  Pointer to "struct tomoyo_name_union".
395  *
396  * Returns nothing.
397  */
398 static void tomoyo_print_name_union_quoted(struct tomoyo_io_buffer *head,
399                                            const struct tomoyo_name_union *ptr)
400 {
401         if (ptr->group) {
402                 tomoyo_set_string(head, "@");
403                 tomoyo_set_string(head, ptr->group->group_name->name);
404         } else {
405                 tomoyo_set_string(head, "\"");
406                 tomoyo_set_string(head, ptr->filename->name);
407                 tomoyo_set_string(head, "\"");
408         }
409 }
410 
411 /**
412  * tomoyo_print_number_union_nospace - Print a tomoyo_number_union without a space.
413  *
414  * @head: Pointer to "struct tomoyo_io_buffer".
415  * @ptr:  Pointer to "struct tomoyo_number_union".
416  *
417  * Returns nothing.
418  */
419 static void tomoyo_print_number_union_nospace
420 (struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr)
421 {
422         if (ptr->group) {
423                 tomoyo_set_string(head, "@");
424                 tomoyo_set_string(head, ptr->group->group_name->name);
425         } else {
426                 int i;
427                 unsigned long min = ptr->values[0];
428                 const unsigned long max = ptr->values[1];
429                 u8 min_type = ptr->value_type[0];
430                 const u8 max_type = ptr->value_type[1];
431                 char buffer[128];
432 
433                 buffer[0] = '\0';
434                 for (i = 0; i < 2; i++) {
435                         switch (min_type) {
436                         case TOMOYO_VALUE_TYPE_HEXADECIMAL:
437                                 tomoyo_addprintf(buffer, sizeof(buffer),
438                                                  "0x%lX", min);
439                                 break;
440                         case TOMOYO_VALUE_TYPE_OCTAL:
441                                 tomoyo_addprintf(buffer, sizeof(buffer),
442                                                  "0%lo", min);
443                                 break;
444                         default:
445                                 tomoyo_addprintf(buffer, sizeof(buffer), "%lu",
446                                                  min);
447                                 break;
448                         }
449                         if (min == max && min_type == max_type)
450                                 break;
451                         tomoyo_addprintf(buffer, sizeof(buffer), "-");
452                         min_type = max_type;
453                         min = max;
454                 }
455                 tomoyo_io_printf(head, "%s", buffer);
456         }
457 }
458 
459 /**
460  * tomoyo_print_number_union - Print a tomoyo_number_union.
461  *
462  * @head: Pointer to "struct tomoyo_io_buffer".
463  * @ptr:  Pointer to "struct tomoyo_number_union".
464  *
465  * Returns nothing.
466  */
467 static void tomoyo_print_number_union(struct tomoyo_io_buffer *head,
468                                       const struct tomoyo_number_union *ptr)
469 {
470         tomoyo_set_space(head);
471         tomoyo_print_number_union_nospace(head, ptr);
472 }
473 
474 /**
475  * tomoyo_assign_profile - Create a new profile.
476  *
477  * @ns:      Pointer to "struct tomoyo_policy_namespace".
478  * @profile: Profile number to create.
479  *
480  * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
481  */
482 static struct tomoyo_profile *tomoyo_assign_profile
483 (struct tomoyo_policy_namespace *ns, const unsigned int profile)
484 {
485         struct tomoyo_profile *ptr;
486         struct tomoyo_profile *entry;
487 
488         if (profile >= TOMOYO_MAX_PROFILES)
489                 return NULL;
490         ptr = ns->profile_ptr[profile];
491         if (ptr)
492                 return ptr;
493         entry = kzalloc(sizeof(*entry), GFP_NOFS | __GFP_NOWARN);
494         if (mutex_lock_interruptible(&tomoyo_policy_lock))
495                 goto out;
496         ptr = ns->profile_ptr[profile];
497         if (!ptr && tomoyo_memory_ok(entry)) {
498                 ptr = entry;
499                 ptr->default_config = TOMOYO_CONFIG_DISABLED |
500                         TOMOYO_CONFIG_WANT_GRANT_LOG |
501                         TOMOYO_CONFIG_WANT_REJECT_LOG;
502                 memset(ptr->config, TOMOYO_CONFIG_USE_DEFAULT,
503                        sizeof(ptr->config));
504                 ptr->pref[TOMOYO_PREF_MAX_AUDIT_LOG] =
505                         CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG;
506                 ptr->pref[TOMOYO_PREF_MAX_LEARNING_ENTRY] =
507                         CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY;
508                 mb(); /* Avoid out-of-order execution. */
509                 ns->profile_ptr[profile] = ptr;
510                 entry = NULL;
511         }
512         mutex_unlock(&tomoyo_policy_lock);
513  out:
514         kfree(entry);
515         return ptr;
516 }
517 
518 /**
519  * tomoyo_profile - Find a profile.
520  *
521  * @ns:      Pointer to "struct tomoyo_policy_namespace".
522  * @profile: Profile number to find.
523  *
524  * Returns pointer to "struct tomoyo_profile".
525  */
526 struct tomoyo_profile *tomoyo_profile(const struct tomoyo_policy_namespace *ns,
527                                       const u8 profile)
528 {
529         static struct tomoyo_profile tomoyo_null_profile;
530         struct tomoyo_profile *ptr = ns->profile_ptr[profile];
531 
532         if (!ptr)
533                 ptr = &tomoyo_null_profile;
534         return ptr;
535 }
536 
537 /**
538  * tomoyo_find_yesno - Find values for specified keyword.
539  *
540  * @string: String to check.
541  * @find:   Name of keyword.
542  *
543  * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise.
544  */
545 static s8 tomoyo_find_yesno(const char *string, const char *find)
546 {
547         const char *cp = strstr(string, find);
548 
549         if (cp) {
550                 cp += strlen(find);
551                 if (!strncmp(cp, "=yes", 4))
552                         return 1;
553                 else if (!strncmp(cp, "=no", 3))
554                         return 0;
555         }
556         return -1;
557 }
558 
559 /**
560  * tomoyo_set_uint - Set value for specified preference.
561  *
562  * @i:      Pointer to "unsigned int".
563  * @string: String to check.
564  * @find:   Name of keyword.
565  *
566  * Returns nothing.
567  */
568 static void tomoyo_set_uint(unsigned int *i, const char *string,
569                             const char *find)
570 {
571         const char *cp = strstr(string, find);
572 
573         if (cp)
574                 sscanf(cp + strlen(find), "=%u", i);
575 }
576 
577 /**
578  * tomoyo_set_mode - Set mode for specified profile.
579  *
580  * @name:    Name of functionality.
581  * @value:   Mode for @name.
582  * @profile: Pointer to "struct tomoyo_profile".
583  *
584  * Returns 0 on success, negative value otherwise.
585  */
586 static int tomoyo_set_mode(char *name, const char *value,
587                            struct tomoyo_profile *profile)
588 {
589         u8 i;
590         u8 config;
591 
592         if (!strcmp(name, "CONFIG")) {
593                 i = TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX;
594                 config = profile->default_config;
595         } else if (tomoyo_str_starts(&name, "CONFIG::")) {
596                 config = 0;
597                 for (i = 0; i < TOMOYO_MAX_MAC_INDEX
598                              + TOMOYO_MAX_MAC_CATEGORY_INDEX; i++) {
599                         int len = 0;
600 
601                         if (i < TOMOYO_MAX_MAC_INDEX) {
602                                 const u8 c = tomoyo_index2category[i];
603                                 const char *category =
604                                         tomoyo_category_keywords[c];
605 
606                                 len = strlen(category);
607                                 if (strncmp(name, category, len) ||
608                                     name[len++] != ':' || name[len++] != ':')
609                                         continue;
610                         }
611                         if (strcmp(name + len, tomoyo_mac_keywords[i]))
612                                 continue;
613                         config = profile->config[i];
614                         break;
615                 }
616                 if (i == TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
617                         return -EINVAL;
618         } else {
619                 return -EINVAL;
620         }
621         if (strstr(value, "use_default")) {
622                 config = TOMOYO_CONFIG_USE_DEFAULT;
623         } else {
624                 u8 mode;
625 
626                 for (mode = 0; mode < 4; mode++)
627                         if (strstr(value, tomoyo_mode[mode]))
628                                 /*
629                                  * Update lower 3 bits in order to distinguish
630                                  * 'config' from 'TOMOYO_CONFIG_USE_DEFAULT'.
631                                  */
632                                 config = (config & ~7) | mode;
633                 if (config != TOMOYO_CONFIG_USE_DEFAULT) {
634                         switch (tomoyo_find_yesno(value, "grant_log")) {
635                         case 1:
636                                 config |= TOMOYO_CONFIG_WANT_GRANT_LOG;
637                                 break;
638                         case 0:
639                                 config &= ~TOMOYO_CONFIG_WANT_GRANT_LOG;
640                                 break;
641                         }
642                         switch (tomoyo_find_yesno(value, "reject_log")) {
643                         case 1:
644                                 config |= TOMOYO_CONFIG_WANT_REJECT_LOG;
645                                 break;
646                         case 0:
647                                 config &= ~TOMOYO_CONFIG_WANT_REJECT_LOG;
648                                 break;
649                         }
650                 }
651         }
652         if (i < TOMOYO_MAX_MAC_INDEX + TOMOYO_MAX_MAC_CATEGORY_INDEX)
653                 profile->config[i] = config;
654         else if (config != TOMOYO_CONFIG_USE_DEFAULT)
655                 profile->default_config = config;
656         return 0;
657 }
658 
659 /**
660  * tomoyo_write_profile - Write profile table.
661  *
662  * @head: Pointer to "struct tomoyo_io_buffer".
663  *
664  * Returns 0 on success, negative value otherwise.
665  */
666 static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
667 {
668         char *data = head->write_buf;
669         unsigned int i;
670         char *cp;
671         struct tomoyo_profile *profile;
672 
673         if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version)
674             == 1)
675                 return 0;
676         i = simple_strtoul(data, &cp, 10);
677         if (*cp != '-')
678                 return -EINVAL;
679         data = cp + 1;
680         profile = tomoyo_assign_profile(head->w.ns, i);
681         if (!profile)
682                 return -EINVAL;
683         cp = strchr(data, '=');
684         if (!cp)
685                 return -EINVAL;
686         *cp++ = '\0';
687         if (!strcmp(data, "COMMENT")) {
688                 static DEFINE_SPINLOCK(lock);
689                 const struct tomoyo_path_info *new_comment
690                         = tomoyo_get_name(cp);
691                 const struct tomoyo_path_info *old_comment;
692 
693                 if (!new_comment)
694                         return -ENOMEM;
695                 spin_lock(&lock);
696                 old_comment = profile->comment;
697                 profile->comment = new_comment;
698                 spin_unlock(&lock);
699                 tomoyo_put_name(old_comment);
700                 return 0;
701         }
702         if (!strcmp(data, "PREFERENCE")) {
703                 for (i = 0; i < TOMOYO_MAX_PREF; i++)
704                         tomoyo_set_uint(&profile->pref[i], cp,
705                                         tomoyo_pref_keywords[i]);
706                 return 0;
707         }
708         return tomoyo_set_mode(data, cp, profile);
709 }
710 
711 /**
712  * tomoyo_print_config - Print mode for specified functionality.
713  *
714  * @head:   Pointer to "struct tomoyo_io_buffer".
715  * @config: Mode for that functionality.
716  *
717  * Returns nothing.
718  *
719  * Caller prints functionality's name.
720  */
721 static void tomoyo_print_config(struct tomoyo_io_buffer *head, const u8 config)
722 {
723         tomoyo_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n",
724                          tomoyo_mode[config & 3],
725                          str_yes_no(config & TOMOYO_CONFIG_WANT_GRANT_LOG),
726                          str_yes_no(config & TOMOYO_CONFIG_WANT_REJECT_LOG));
727 }
728 
729 /**
730  * tomoyo_read_profile - Read profile table.
731  *
732  * @head: Pointer to "struct tomoyo_io_buffer".
733  *
734  * Returns nothing.
735  */
736 static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
737 {
738         u8 index;
739         struct tomoyo_policy_namespace *ns =
740                 container_of(head->r.ns, typeof(*ns), namespace_list);
741         const struct tomoyo_profile *profile;
742 
743         if (head->r.eof)
744                 return;
745  next:
746         index = head->r.index;
747         profile = ns->profile_ptr[index];
748         switch (head->r.step) {
749         case 0:
750                 tomoyo_print_namespace(head);
751                 tomoyo_io_printf(head, "PROFILE_VERSION=%u\n",
752                                  ns->profile_version);
753                 head->r.step++;
754                 break;
755         case 1:
756                 for ( ; head->r.index < TOMOYO_MAX_PROFILES;
757                       head->r.index++)
758                         if (ns->profile_ptr[head->r.index])
759                                 break;
760                 if (head->r.index == TOMOYO_MAX_PROFILES) {
761                         head->r.eof = true;
762                         return;
763                 }
764                 head->r.step++;
765                 break;
766         case 2:
767                 {
768                         u8 i;
769                         const struct tomoyo_path_info *comment =
770                                 profile->comment;
771 
772                         tomoyo_print_namespace(head);
773                         tomoyo_io_printf(head, "%u-COMMENT=", index);
774                         tomoyo_set_string(head, comment ? comment->name : "");
775                         tomoyo_set_lf(head);
776                         tomoyo_print_namespace(head);
777                         tomoyo_io_printf(head, "%u-PREFERENCE={ ", index);
778                         for (i = 0; i < TOMOYO_MAX_PREF; i++)
779                                 tomoyo_io_printf(head, "%s=%u ",
780                                                  tomoyo_pref_keywords[i],
781                                                  profile->pref[i]);
782                         tomoyo_set_string(head, "}\n");
783                         head->r.step++;
784                 }
785                 break;
786         case 3:
787                 {
788                         tomoyo_print_namespace(head);
789                         tomoyo_io_printf(head, "%u-%s", index, "CONFIG");
790                         tomoyo_print_config(head, profile->default_config);
791                         head->r.bit = 0;
792                         head->r.step++;
793                 }
794                 break;
795         case 4:
796                 for ( ; head->r.bit < TOMOYO_MAX_MAC_INDEX
797                               + TOMOYO_MAX_MAC_CATEGORY_INDEX; head->r.bit++) {
798                         const u8 i = head->r.bit;
799                         const u8 config = profile->config[i];
800 
801                         if (config == TOMOYO_CONFIG_USE_DEFAULT)
802                                 continue;
803                         tomoyo_print_namespace(head);
804                         if (i < TOMOYO_MAX_MAC_INDEX)
805                                 tomoyo_io_printf(head, "%u-CONFIG::%s::%s",
806                                                  index,
807                                                  tomoyo_category_keywords
808                                                  [tomoyo_index2category[i]],
809                                                  tomoyo_mac_keywords[i]);
810                         else
811                                 tomoyo_io_printf(head, "%u-CONFIG::%s", index,
812                                                  tomoyo_mac_keywords[i]);
813                         tomoyo_print_config(head, config);
814                         head->r.bit++;
815                         break;
816                 }
817                 if (head->r.bit == TOMOYO_MAX_MAC_INDEX
818                     + TOMOYO_MAX_MAC_CATEGORY_INDEX) {
819                         head->r.index++;
820                         head->r.step = 1;
821                 }
822                 break;
823         }
824         if (tomoyo_flush(head))
825                 goto next;
826 }
827 
828 /**
829  * tomoyo_same_manager - Check for duplicated "struct tomoyo_manager" entry.
830  *
831  * @a: Pointer to "struct tomoyo_acl_head".
832  * @b: Pointer to "struct tomoyo_acl_head".
833  *
834  * Returns true if @a == @b, false otherwise.
835  */
836 static bool tomoyo_same_manager(const struct tomoyo_acl_head *a,
837                                 const struct tomoyo_acl_head *b)
838 {
839         return container_of(a, struct tomoyo_manager, head)->manager ==
840                 container_of(b, struct tomoyo_manager, head)->manager;
841 }
842 
843 /**
844  * tomoyo_update_manager_entry - Add a manager entry.
845  *
846  * @manager:   The path to manager or the domainnamme.
847  * @is_delete: True if it is a delete request.
848  *
849  * Returns 0 on success, negative value otherwise.
850  *
851  * Caller holds tomoyo_read_lock().
852  */
853 static int tomoyo_update_manager_entry(const char *manager,
854                                        const bool is_delete)
855 {
856         struct tomoyo_manager e = { };
857         struct tomoyo_acl_param param = {
858                 /* .ns = &tomoyo_kernel_namespace, */
859                 .is_delete = is_delete,
860                 .list = &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER],
861         };
862         int error = is_delete ? -ENOENT : -ENOMEM;
863 
864         if (!tomoyo_correct_domain(manager) &&
865             !tomoyo_correct_word(manager))
866                 return -EINVAL;
867         e.manager = tomoyo_get_name(manager);
868         if (e.manager) {
869                 error = tomoyo_update_policy(&e.head, sizeof(e), &param,
870                                              tomoyo_same_manager);
871                 tomoyo_put_name(e.manager);
872         }
873         return error;
874 }
875 
876 /**
877  * tomoyo_write_manager - Write manager policy.
878  *
879  * @head: Pointer to "struct tomoyo_io_buffer".
880  *
881  * Returns 0 on success, negative value otherwise.
882  *
883  * Caller holds tomoyo_read_lock().
884  */
885 static int tomoyo_write_manager(struct tomoyo_io_buffer *head)
886 {
887         char *data = head->write_buf;
888 
889         if (!strcmp(data, "manage_by_non_root")) {
890                 tomoyo_manage_by_non_root = !head->w.is_delete;
891                 return 0;
892         }
893         return tomoyo_update_manager_entry(data, head->w.is_delete);
894 }
895 
896 /**
897  * tomoyo_read_manager - Read manager policy.
898  *
899  * @head: Pointer to "struct tomoyo_io_buffer".
900  *
901  * Caller holds tomoyo_read_lock().
902  */
903 static void tomoyo_read_manager(struct tomoyo_io_buffer *head)
904 {
905         if (head->r.eof)
906                 return;
907         list_for_each_cookie(head->r.acl, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER]) {
908                 struct tomoyo_manager *ptr =
909                         list_entry(head->r.acl, typeof(*ptr), head.list);
910 
911                 if (ptr->head.is_deleted)
912                         continue;
913                 if (!tomoyo_flush(head))
914                         return;
915                 tomoyo_set_string(head, ptr->manager->name);
916                 tomoyo_set_lf(head);
917         }
918         head->r.eof = true;
919 }
920 
921 /**
922  * tomoyo_manager - Check whether the current process is a policy manager.
923  *
924  * Returns true if the current process is permitted to modify policy
925  * via /sys/kernel/security/tomoyo/ interface.
926  *
927  * Caller holds tomoyo_read_lock().
928  */
929 static bool tomoyo_manager(void)
930 {
931         struct tomoyo_manager *ptr;
932         const char *exe;
933         const struct task_struct *task = current;
934         const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
935         bool found = IS_ENABLED(CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING);
936 
937         if (!tomoyo_policy_loaded)
938                 return true;
939         if (!tomoyo_manage_by_non_root &&
940             (!uid_eq(task->cred->uid,  GLOBAL_ROOT_UID) ||
941              !uid_eq(task->cred->euid, GLOBAL_ROOT_UID)))
942                 return false;
943         exe = tomoyo_get_exe();
944         if (!exe)
945                 return false;
946         list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list,
947                                 srcu_read_lock_held(&tomoyo_ss)) {
948                 if (!ptr->head.is_deleted &&
949                     (!tomoyo_pathcmp(domainname, ptr->manager) ||
950                      !strcmp(exe, ptr->manager->name))) {
951                         found = true;
952                         break;
953                 }
954         }
955         if (!found) { /* Reduce error messages. */
956                 static pid_t last_pid;
957                 const pid_t pid = current->pid;
958 
959                 if (last_pid != pid) {
960                         pr_warn("%s ( %s ) is not permitted to update policies.\n",
961                                 domainname->name, exe);
962                         last_pid = pid;
963                 }
964         }
965         kfree(exe);
966         return found;
967 }
968 
969 static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
970 (unsigned int serial);
971 
972 /**
973  * tomoyo_select_domain - Parse select command.
974  *
975  * @head: Pointer to "struct tomoyo_io_buffer".
976  * @data: String to parse.
977  *
978  * Returns true on success, false otherwise.
979  *
980  * Caller holds tomoyo_read_lock().
981  */
982 static bool tomoyo_select_domain(struct tomoyo_io_buffer *head,
983                                  const char *data)
984 {
985         unsigned int pid;
986         struct tomoyo_domain_info *domain = NULL;
987         bool global_pid = false;
988 
989         if (strncmp(data, "select ", 7))
990                 return false;
991         data += 7;
992         if (sscanf(data, "pid=%u", &pid) == 1 ||
993             (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) {
994                 struct task_struct *p;
995 
996                 rcu_read_lock();
997                 if (global_pid)
998                         p = find_task_by_pid_ns(pid, &init_pid_ns);
999                 else
1000                         p = find_task_by_vpid(pid);
1001                 if (p)
1002                         domain = tomoyo_task(p)->domain_info;
1003                 rcu_read_unlock();
1004         } else if (!strncmp(data, "domain=", 7)) {
1005                 if (tomoyo_domain_def(data + 7))
1006                         domain = tomoyo_find_domain(data + 7);
1007         } else if (sscanf(data, "Q=%u", &pid) == 1) {
1008                 domain = tomoyo_find_domain_by_qid(pid);
1009         } else
1010                 return false;
1011         head->w.domain = domain;
1012         /* Accessing read_buf is safe because head->io_sem is held. */
1013         if (!head->read_buf)
1014                 return true; /* Do nothing if open(O_WRONLY). */
1015         memset(&head->r, 0, sizeof(head->r));
1016         head->r.print_this_domain_only = true;
1017         if (domain)
1018                 head->r.domain = &domain->list;
1019         else
1020                 head->r.eof = true;
1021         tomoyo_io_printf(head, "# select %s\n", data);
1022         if (domain && domain->is_deleted)
1023                 tomoyo_io_printf(head, "# This is a deleted domain.\n");
1024         return true;
1025 }
1026 
1027 /**
1028  * tomoyo_same_task_acl - Check for duplicated "struct tomoyo_task_acl" entry.
1029  *
1030  * @a: Pointer to "struct tomoyo_acl_info".
1031  * @b: Pointer to "struct tomoyo_acl_info".
1032  *
1033  * Returns true if @a == @b, false otherwise.
1034  */
1035 static bool tomoyo_same_task_acl(const struct tomoyo_acl_info *a,
1036                                  const struct tomoyo_acl_info *b)
1037 {
1038         const struct tomoyo_task_acl *p1 = container_of(a, typeof(*p1), head);
1039         const struct tomoyo_task_acl *p2 = container_of(b, typeof(*p2), head);
1040 
1041         return p1->domainname == p2->domainname;
1042 }
1043 
1044 /**
1045  * tomoyo_write_task - Update task related list.
1046  *
1047  * @param: Pointer to "struct tomoyo_acl_param".
1048  *
1049  * Returns 0 on success, negative value otherwise.
1050  *
1051  * Caller holds tomoyo_read_lock().
1052  */
1053 static int tomoyo_write_task(struct tomoyo_acl_param *param)
1054 {
1055         int error = -EINVAL;
1056 
1057         if (tomoyo_str_starts(&param->data, "manual_domain_transition ")) {
1058                 struct tomoyo_task_acl e = {
1059                         .head.type = TOMOYO_TYPE_MANUAL_TASK_ACL,
1060                         .domainname = tomoyo_get_domainname(param),
1061                 };
1062 
1063                 if (e.domainname)
1064                         error = tomoyo_update_domain(&e.head, sizeof(e), param,
1065                                                      tomoyo_same_task_acl,
1066                                                      NULL);
1067                 tomoyo_put_name(e.domainname);
1068         }
1069         return error;
1070 }
1071 
1072 /**
1073  * tomoyo_delete_domain - Delete a domain.
1074  *
1075  * @domainname: The name of domain.
1076  *
1077  * Returns 0 on success, negative value otherwise.
1078  *
1079  * Caller holds tomoyo_read_lock().
1080  */
1081 static int tomoyo_delete_domain(char *domainname)
1082 {
1083         struct tomoyo_domain_info *domain;
1084         struct tomoyo_path_info name;
1085 
1086         name.name = domainname;
1087         tomoyo_fill_path_info(&name);
1088         if (mutex_lock_interruptible(&tomoyo_policy_lock))
1089                 return -EINTR;
1090         /* Is there an active domain? */
1091         list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
1092                                 srcu_read_lock_held(&tomoyo_ss)) {
1093                 /* Never delete tomoyo_kernel_domain */
1094                 if (domain == &tomoyo_kernel_domain)
1095                         continue;
1096                 if (domain->is_deleted ||
1097                     tomoyo_pathcmp(domain->domainname, &name))
1098                         continue;
1099                 domain->is_deleted = true;
1100                 break;
1101         }
1102         mutex_unlock(&tomoyo_policy_lock);
1103         return 0;
1104 }
1105 
1106 /**
1107  * tomoyo_write_domain2 - Write domain policy.
1108  *
1109  * @ns:        Pointer to "struct tomoyo_policy_namespace".
1110  * @list:      Pointer to "struct list_head".
1111  * @data:      Policy to be interpreted.
1112  * @is_delete: True if it is a delete request.
1113  *
1114  * Returns 0 on success, negative value otherwise.
1115  *
1116  * Caller holds tomoyo_read_lock().
1117  */
1118 static int tomoyo_write_domain2(struct tomoyo_policy_namespace *ns,
1119                                 struct list_head *list, char *data,
1120                                 const bool is_delete)
1121 {
1122         struct tomoyo_acl_param param = {
1123                 .ns = ns,
1124                 .list = list,
1125                 .data = data,
1126                 .is_delete = is_delete,
1127         };
1128         static const struct {
1129                 const char *keyword;
1130                 int (*write)(struct tomoyo_acl_param *param);
1131         } tomoyo_callback[5] = {
1132                 { "file ", tomoyo_write_file },
1133                 { "network inet ", tomoyo_write_inet_network },
1134                 { "network unix ", tomoyo_write_unix_network },
1135                 { "misc ", tomoyo_write_misc },
1136                 { "task ", tomoyo_write_task },
1137         };
1138         u8 i;
1139 
1140         for (i = 0; i < ARRAY_SIZE(tomoyo_callback); i++) {
1141                 if (!tomoyo_str_starts(&param.data,
1142                                        tomoyo_callback[i].keyword))
1143                         continue;
1144                 return tomoyo_callback[i].write(&param);
1145         }
1146         return -EINVAL;
1147 }
1148 
1149 /* String table for domain flags. */
1150 const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS] = {
1151         [TOMOYO_DIF_QUOTA_WARNED]      = "quota_exceeded\n",
1152         [TOMOYO_DIF_TRANSITION_FAILED] = "transition_failed\n",
1153 };
1154 
1155 /**
1156  * tomoyo_write_domain - Write domain policy.
1157  *
1158  * @head: Pointer to "struct tomoyo_io_buffer".
1159  *
1160  * Returns 0 on success, negative value otherwise.
1161  *
1162  * Caller holds tomoyo_read_lock().
1163  */
1164 static int tomoyo_write_domain(struct tomoyo_io_buffer *head)
1165 {
1166         char *data = head->write_buf;
1167         struct tomoyo_policy_namespace *ns;
1168         struct tomoyo_domain_info *domain = head->w.domain;
1169         const bool is_delete = head->w.is_delete;
1170         bool is_select = !is_delete && tomoyo_str_starts(&data, "select ");
1171         unsigned int idx;
1172 
1173         if (*data == '<') {
1174                 int ret = 0;
1175 
1176                 domain = NULL;
1177                 if (is_delete)
1178                         ret = tomoyo_delete_domain(data);
1179                 else if (is_select)
1180                         domain = tomoyo_find_domain(data);
1181                 else
1182                         domain = tomoyo_assign_domain(data, false);
1183                 head->w.domain = domain;
1184                 return ret;
1185         }
1186         if (!domain)
1187                 return -EINVAL;
1188         ns = domain->ns;
1189         if (sscanf(data, "use_profile %u", &idx) == 1
1190             && idx < TOMOYO_MAX_PROFILES) {
1191                 if (!tomoyo_policy_loaded || ns->profile_ptr[idx])
1192                         if (!is_delete)
1193                                 domain->profile = (u8) idx;
1194                 return 0;
1195         }
1196         if (sscanf(data, "use_group %u\n", &idx) == 1
1197             && idx < TOMOYO_MAX_ACL_GROUPS) {
1198                 if (!is_delete)
1199                         set_bit(idx, domain->group);
1200                 else
1201                         clear_bit(idx, domain->group);
1202                 return 0;
1203         }
1204         for (idx = 0; idx < TOMOYO_MAX_DOMAIN_INFO_FLAGS; idx++) {
1205                 const char *cp = tomoyo_dif[idx];
1206 
1207                 if (strncmp(data, cp, strlen(cp) - 1))
1208                         continue;
1209                 domain->flags[idx] = !is_delete;
1210                 return 0;
1211         }
1212         return tomoyo_write_domain2(ns, &domain->acl_info_list, data,
1213                                     is_delete);
1214 }
1215 
1216 /**
1217  * tomoyo_print_condition - Print condition part.
1218  *
1219  * @head: Pointer to "struct tomoyo_io_buffer".
1220  * @cond: Pointer to "struct tomoyo_condition".
1221  *
1222  * Returns true on success, false otherwise.
1223  */
1224 static bool tomoyo_print_condition(struct tomoyo_io_buffer *head,
1225                                    const struct tomoyo_condition *cond)
1226 {
1227         switch (head->r.cond_step) {
1228         case 0:
1229                 head->r.cond_index = 0;
1230                 head->r.cond_step++;
1231                 if (cond->transit) {
1232                         tomoyo_set_space(head);
1233                         tomoyo_set_string(head, cond->transit->name);
1234                 }
1235                 fallthrough;
1236         case 1:
1237                 {
1238                         const u16 condc = cond->condc;
1239                         const struct tomoyo_condition_element *condp =
1240                                 (typeof(condp)) (cond + 1);
1241                         const struct tomoyo_number_union *numbers_p =
1242                                 (typeof(numbers_p)) (condp + condc);
1243                         const struct tomoyo_name_union *names_p =
1244                                 (typeof(names_p))
1245                                 (numbers_p + cond->numbers_count);
1246                         const struct tomoyo_argv *argv =
1247                                 (typeof(argv)) (names_p + cond->names_count);
1248                         const struct tomoyo_envp *envp =
1249                                 (typeof(envp)) (argv + cond->argc);
1250                         u16 skip;
1251 
1252                         for (skip = 0; skip < head->r.cond_index; skip++) {
1253                                 const u8 left = condp->left;
1254                                 const u8 right = condp->right;
1255 
1256                                 condp++;
1257                                 switch (left) {
1258                                 case TOMOYO_ARGV_ENTRY:
1259                                         argv++;
1260                                         continue;
1261                                 case TOMOYO_ENVP_ENTRY:
1262                                         envp++;
1263                                         continue;
1264                                 case TOMOYO_NUMBER_UNION:
1265                                         numbers_p++;
1266                                         break;
1267                                 }
1268                                 switch (right) {
1269                                 case TOMOYO_NAME_UNION:
1270                                         names_p++;
1271                                         break;
1272                                 case TOMOYO_NUMBER_UNION:
1273                                         numbers_p++;
1274                                         break;
1275                                 }
1276                         }
1277                         while (head->r.cond_index < condc) {
1278                                 const u8 match = condp->equals;
1279                                 const u8 left = condp->left;
1280                                 const u8 right = condp->right;
1281 
1282                                 if (!tomoyo_flush(head))
1283                                         return false;
1284                                 condp++;
1285                                 head->r.cond_index++;
1286                                 tomoyo_set_space(head);
1287                                 switch (left) {
1288                                 case TOMOYO_ARGV_ENTRY:
1289                                         tomoyo_io_printf(head,
1290                                                          "exec.argv[%lu]%s=\"",
1291                                                          argv->index, argv->is_not ? "!" : "");
1292                                         tomoyo_set_string(head,
1293                                                           argv->value->name);
1294                                         tomoyo_set_string(head, "\"");
1295                                         argv++;
1296                                         continue;
1297                                 case TOMOYO_ENVP_ENTRY:
1298                                         tomoyo_set_string(head,
1299                                                           "exec.envp[\"");
1300                                         tomoyo_set_string(head,
1301                                                           envp->name->name);
1302                                         tomoyo_io_printf(head, "\"]%s=", envp->is_not ? "!" : "");
1303                                         if (envp->value) {
1304                                                 tomoyo_set_string(head, "\"");
1305                                                 tomoyo_set_string(head, envp->value->name);
1306                                                 tomoyo_set_string(head, "\"");
1307                                         } else {
1308                                                 tomoyo_set_string(head,
1309                                                                   "NULL");
1310                                         }
1311                                         envp++;
1312                                         continue;
1313                                 case TOMOYO_NUMBER_UNION:
1314                                         tomoyo_print_number_union_nospace
1315                                                 (head, numbers_p++);
1316                                         break;
1317                                 default:
1318                                         tomoyo_set_string(head,
1319                                                tomoyo_condition_keyword[left]);
1320                                         break;
1321                                 }
1322                                 tomoyo_set_string(head, match ? "=" : "!=");
1323                                 switch (right) {
1324                                 case TOMOYO_NAME_UNION:
1325                                         tomoyo_print_name_union_quoted
1326                                                 (head, names_p++);
1327                                         break;
1328                                 case TOMOYO_NUMBER_UNION:
1329                                         tomoyo_print_number_union_nospace
1330                                                 (head, numbers_p++);
1331                                         break;
1332                                 default:
1333                                         tomoyo_set_string(head,
1334                                           tomoyo_condition_keyword[right]);
1335                                         break;
1336                                 }
1337                         }
1338                 }
1339                 head->r.cond_step++;
1340                 fallthrough;
1341         case 2:
1342                 if (!tomoyo_flush(head))
1343                         break;
1344                 head->r.cond_step++;
1345                 fallthrough;
1346         case 3:
1347                 if (cond->grant_log != TOMOYO_GRANTLOG_AUTO)
1348                         tomoyo_io_printf(head, " grant_log=%s",
1349                                          str_yes_no(cond->grant_log ==
1350                                                     TOMOYO_GRANTLOG_YES));
1351                 tomoyo_set_lf(head);
1352                 return true;
1353         }
1354         return false;
1355 }
1356 
1357 /**
1358  * tomoyo_set_group - Print "acl_group " header keyword and category name.
1359  *
1360  * @head:     Pointer to "struct tomoyo_io_buffer".
1361  * @category: Category name.
1362  *
1363  * Returns nothing.
1364  */
1365 static void tomoyo_set_group(struct tomoyo_io_buffer *head,
1366                              const char *category)
1367 {
1368         if (head->type == TOMOYO_EXCEPTIONPOLICY) {
1369                 tomoyo_print_namespace(head);
1370                 tomoyo_io_printf(head, "acl_group %u ",
1371                                  head->r.acl_group_index);
1372         }
1373         tomoyo_set_string(head, category);
1374 }
1375 
1376 /**
1377  * tomoyo_print_entry - Print an ACL entry.
1378  *
1379  * @head: Pointer to "struct tomoyo_io_buffer".
1380  * @acl:  Pointer to an ACL entry.
1381  *
1382  * Returns true on success, false otherwise.
1383  */
1384 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1385                                struct tomoyo_acl_info *acl)
1386 {
1387         const u8 acl_type = acl->type;
1388         bool first = true;
1389         u8 bit;
1390 
1391         if (head->r.print_cond_part)
1392                 goto print_cond_part;
1393         if (acl->is_deleted)
1394                 return true;
1395         if (!tomoyo_flush(head))
1396                 return false;
1397         else if (acl_type == TOMOYO_TYPE_PATH_ACL) {
1398                 struct tomoyo_path_acl *ptr =
1399                         container_of(acl, typeof(*ptr), head);
1400                 const u16 perm = ptr->perm;
1401 
1402                 for (bit = 0; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
1403                         if (!(perm & (1 << bit)))
1404                                 continue;
1405                         if (head->r.print_transition_related_only &&
1406                             bit != TOMOYO_TYPE_EXECUTE)
1407                                 continue;
1408                         if (first) {
1409                                 tomoyo_set_group(head, "file ");
1410                                 first = false;
1411                         } else {
1412                                 tomoyo_set_slash(head);
1413                         }
1414                         tomoyo_set_string(head, tomoyo_path_keyword[bit]);
1415                 }
1416                 if (first)
1417                         return true;
1418                 tomoyo_print_name_union(head, &ptr->name);
1419         } else if (acl_type == TOMOYO_TYPE_MANUAL_TASK_ACL) {
1420                 struct tomoyo_task_acl *ptr =
1421                         container_of(acl, typeof(*ptr), head);
1422 
1423                 tomoyo_set_group(head, "task ");
1424                 tomoyo_set_string(head, "manual_domain_transition ");
1425                 tomoyo_set_string(head, ptr->domainname->name);
1426         } else if (head->r.print_transition_related_only) {
1427                 return true;
1428         } else if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
1429                 struct tomoyo_path2_acl *ptr =
1430                         container_of(acl, typeof(*ptr), head);
1431                 const u8 perm = ptr->perm;
1432 
1433                 for (bit = 0; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
1434                         if (!(perm & (1 << bit)))
1435                                 continue;
1436                         if (first) {
1437                                 tomoyo_set_group(head, "file ");
1438                                 first = false;
1439                         } else {
1440                                 tomoyo_set_slash(head);
1441                         }
1442                         tomoyo_set_string(head, tomoyo_mac_keywords
1443                                           [tomoyo_pp2mac[bit]]);
1444                 }
1445                 if (first)
1446                         return true;
1447                 tomoyo_print_name_union(head, &ptr->name1);
1448                 tomoyo_print_name_union(head, &ptr->name2);
1449         } else if (acl_type == TOMOYO_TYPE_PATH_NUMBER_ACL) {
1450                 struct tomoyo_path_number_acl *ptr =
1451                         container_of(acl, typeof(*ptr), head);
1452                 const u8 perm = ptr->perm;
1453 
1454                 for (bit = 0; bit < TOMOYO_MAX_PATH_NUMBER_OPERATION; bit++) {
1455                         if (!(perm & (1 << bit)))
1456                                 continue;
1457                         if (first) {
1458                                 tomoyo_set_group(head, "file ");
1459                                 first = false;
1460                         } else {
1461                                 tomoyo_set_slash(head);
1462                         }
1463                         tomoyo_set_string(head, tomoyo_mac_keywords
1464                                           [tomoyo_pn2mac[bit]]);
1465                 }
1466                 if (first)
1467                         return true;
1468                 tomoyo_print_name_union(head, &ptr->name);
1469                 tomoyo_print_number_union(head, &ptr->number);
1470         } else if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
1471                 struct tomoyo_mkdev_acl *ptr =
1472                         container_of(acl, typeof(*ptr), head);
1473                 const u8 perm = ptr->perm;
1474 
1475                 for (bit = 0; bit < TOMOYO_MAX_MKDEV_OPERATION; bit++) {
1476                         if (!(perm & (1 << bit)))
1477                                 continue;
1478                         if (first) {
1479                                 tomoyo_set_group(head, "file ");
1480                                 first = false;
1481                         } else {
1482                                 tomoyo_set_slash(head);
1483                         }
1484                         tomoyo_set_string(head, tomoyo_mac_keywords
1485                                           [tomoyo_pnnn2mac[bit]]);
1486                 }
1487                 if (first)
1488                         return true;
1489                 tomoyo_print_name_union(head, &ptr->name);
1490                 tomoyo_print_number_union(head, &ptr->mode);
1491                 tomoyo_print_number_union(head, &ptr->major);
1492                 tomoyo_print_number_union(head, &ptr->minor);
1493         } else if (acl_type == TOMOYO_TYPE_INET_ACL) {
1494                 struct tomoyo_inet_acl *ptr =
1495                         container_of(acl, typeof(*ptr), head);
1496                 const u8 perm = ptr->perm;
1497 
1498                 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
1499                         if (!(perm & (1 << bit)))
1500                                 continue;
1501                         if (first) {
1502                                 tomoyo_set_group(head, "network inet ");
1503                                 tomoyo_set_string(head, tomoyo_proto_keyword
1504                                                   [ptr->protocol]);
1505                                 tomoyo_set_space(head);
1506                                 first = false;
1507                         } else {
1508                                 tomoyo_set_slash(head);
1509                         }
1510                         tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
1511                 }
1512                 if (first)
1513                         return true;
1514                 tomoyo_set_space(head);
1515                 if (ptr->address.group) {
1516                         tomoyo_set_string(head, "@");
1517                         tomoyo_set_string(head, ptr->address.group->group_name
1518                                           ->name);
1519                 } else {
1520                         char buf[128];
1521 
1522                         tomoyo_print_ip(buf, sizeof(buf), &ptr->address);
1523                         tomoyo_io_printf(head, "%s", buf);
1524                 }
1525                 tomoyo_print_number_union(head, &ptr->port);
1526         } else if (acl_type == TOMOYO_TYPE_UNIX_ACL) {
1527                 struct tomoyo_unix_acl *ptr =
1528                         container_of(acl, typeof(*ptr), head);
1529                 const u8 perm = ptr->perm;
1530 
1531                 for (bit = 0; bit < TOMOYO_MAX_NETWORK_OPERATION; bit++) {
1532                         if (!(perm & (1 << bit)))
1533                                 continue;
1534                         if (first) {
1535                                 tomoyo_set_group(head, "network unix ");
1536                                 tomoyo_set_string(head, tomoyo_proto_keyword
1537                                                   [ptr->protocol]);
1538                                 tomoyo_set_space(head);
1539                                 first = false;
1540                         } else {
1541                                 tomoyo_set_slash(head);
1542                         }
1543                         tomoyo_set_string(head, tomoyo_socket_keyword[bit]);
1544                 }
1545                 if (first)
1546                         return true;
1547                 tomoyo_print_name_union(head, &ptr->name);
1548         } else if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
1549                 struct tomoyo_mount_acl *ptr =
1550                         container_of(acl, typeof(*ptr), head);
1551 
1552                 tomoyo_set_group(head, "file mount");
1553                 tomoyo_print_name_union(head, &ptr->dev_name);
1554                 tomoyo_print_name_union(head, &ptr->dir_name);
1555                 tomoyo_print_name_union(head, &ptr->fs_type);
1556                 tomoyo_print_number_union(head, &ptr->flags);
1557         } else if (acl_type == TOMOYO_TYPE_ENV_ACL) {
1558                 struct tomoyo_env_acl *ptr =
1559                         container_of(acl, typeof(*ptr), head);
1560 
1561                 tomoyo_set_group(head, "misc env ");
1562                 tomoyo_set_string(head, ptr->env->name);
1563         }
1564         if (acl->cond) {
1565                 head->r.print_cond_part = true;
1566                 head->r.cond_step = 0;
1567                 if (!tomoyo_flush(head))
1568                         return false;
1569 print_cond_part:
1570                 if (!tomoyo_print_condition(head, acl->cond))
1571                         return false;
1572                 head->r.print_cond_part = false;
1573         } else {
1574                 tomoyo_set_lf(head);
1575         }
1576         return true;
1577 }
1578 
1579 /**
1580  * tomoyo_read_domain2 - Read domain policy.
1581  *
1582  * @head: Pointer to "struct tomoyo_io_buffer".
1583  * @list: Pointer to "struct list_head".
1584  *
1585  * Caller holds tomoyo_read_lock().
1586  *
1587  * Returns true on success, false otherwise.
1588  */
1589 static bool tomoyo_read_domain2(struct tomoyo_io_buffer *head,
1590                                 struct list_head *list)
1591 {
1592         list_for_each_cookie(head->r.acl, list) {
1593                 struct tomoyo_acl_info *ptr =
1594                         list_entry(head->r.acl, typeof(*ptr), list);
1595 
1596                 if (!tomoyo_print_entry(head, ptr))
1597                         return false;
1598         }
1599         head->r.acl = NULL;
1600         return true;
1601 }
1602 
1603 /**
1604  * tomoyo_read_domain - Read domain policy.
1605  *
1606  * @head: Pointer to "struct tomoyo_io_buffer".
1607  *
1608  * Caller holds tomoyo_read_lock().
1609  */
1610 static void tomoyo_read_domain(struct tomoyo_io_buffer *head)
1611 {
1612         if (head->r.eof)
1613                 return;
1614         list_for_each_cookie(head->r.domain, &tomoyo_domain_list) {
1615                 struct tomoyo_domain_info *domain =
1616                         list_entry(head->r.domain, typeof(*domain), list);
1617                 u8 i;
1618 
1619                 switch (head->r.step) {
1620                 case 0:
1621                         if (domain->is_deleted &&
1622                             !head->r.print_this_domain_only)
1623                                 continue;
1624                         /* Print domainname and flags. */
1625                         tomoyo_set_string(head, domain->domainname->name);
1626                         tomoyo_set_lf(head);
1627                         tomoyo_io_printf(head, "use_profile %u\n",
1628                                          domain->profile);
1629                         for (i = 0; i < TOMOYO_MAX_DOMAIN_INFO_FLAGS; i++)
1630                                 if (domain->flags[i])
1631                                         tomoyo_set_string(head, tomoyo_dif[i]);
1632                         head->r.index = 0;
1633                         head->r.step++;
1634                         fallthrough;
1635                 case 1:
1636                         while (head->r.index < TOMOYO_MAX_ACL_GROUPS) {
1637                                 i = head->r.index++;
1638                                 if (!test_bit(i, domain->group))
1639                                         continue;
1640                                 tomoyo_io_printf(head, "use_group %u\n", i);
1641                                 if (!tomoyo_flush(head))
1642                                         return;
1643                         }
1644                         head->r.index = 0;
1645                         head->r.step++;
1646                         tomoyo_set_lf(head);
1647                         fallthrough;
1648                 case 2:
1649                         if (!tomoyo_read_domain2(head, &domain->acl_info_list))
1650                                 return;
1651                         head->r.step++;
1652                         if (!tomoyo_set_lf(head))
1653                                 return;
1654                         fallthrough;
1655                 case 3:
1656                         head->r.step = 0;
1657                         if (head->r.print_this_domain_only)
1658                                 goto done;
1659                 }
1660         }
1661  done:
1662         head->r.eof = true;
1663 }
1664 
1665 /**
1666  * tomoyo_write_pid: Specify PID to obtain domainname.
1667  *
1668  * @head: Pointer to "struct tomoyo_io_buffer".
1669  *
1670  * Returns 0.
1671  */
1672 static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
1673 {
1674         head->r.eof = false;
1675         return 0;
1676 }
1677 
1678 /**
1679  * tomoyo_read_pid - Get domainname of the specified PID.
1680  *
1681  * @head: Pointer to "struct tomoyo_io_buffer".
1682  *
1683  * Returns the domainname which the specified PID is in on success,
1684  * empty string otherwise.
1685  * The PID is specified by tomoyo_write_pid() so that the user can obtain
1686  * using read()/write() interface rather than sysctl() interface.
1687  */
1688 static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
1689 {
1690         char *buf = head->write_buf;
1691         bool global_pid = false;
1692         unsigned int pid;
1693         struct task_struct *p;
1694         struct tomoyo_domain_info *domain = NULL;
1695 
1696         /* Accessing write_buf is safe because head->io_sem is held. */
1697         if (!buf) {
1698                 head->r.eof = true;
1699                 return; /* Do nothing if open(O_RDONLY). */
1700         }
1701         if (head->r.w_pos || head->r.eof)
1702                 return;
1703         head->r.eof = true;
1704         if (tomoyo_str_starts(&buf, "global-pid "))
1705                 global_pid = true;
1706         if (kstrtouint(buf, 10, &pid))
1707                 return;
1708         rcu_read_lock();
1709         if (global_pid)
1710                 p = find_task_by_pid_ns(pid, &init_pid_ns);
1711         else
1712                 p = find_task_by_vpid(pid);
1713         if (p)
1714                 domain = tomoyo_task(p)->domain_info;
1715         rcu_read_unlock();
1716         if (!domain)
1717                 return;
1718         tomoyo_io_printf(head, "%u %u ", pid, domain->profile);
1719         tomoyo_set_string(head, domain->domainname->name);
1720 }
1721 
1722 /* String table for domain transition control keywords. */
1723 static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
1724         [TOMOYO_TRANSITION_CONTROL_NO_RESET]      = "no_reset_domain ",
1725         [TOMOYO_TRANSITION_CONTROL_RESET]         = "reset_domain ",
1726         [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
1727         [TOMOYO_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
1728         [TOMOYO_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
1729         [TOMOYO_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
1730 };
1731 
1732 /* String table for grouping keywords. */
1733 static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
1734         [TOMOYO_PATH_GROUP]    = "path_group ",
1735         [TOMOYO_NUMBER_GROUP]  = "number_group ",
1736         [TOMOYO_ADDRESS_GROUP] = "address_group ",
1737 };
1738 
1739 /**
1740  * tomoyo_write_exception - Write exception policy.
1741  *
1742  * @head: Pointer to "struct tomoyo_io_buffer".
1743  *
1744  * Returns 0 on success, negative value otherwise.
1745  *
1746  * Caller holds tomoyo_read_lock().
1747  */
1748 static int tomoyo_write_exception(struct tomoyo_io_buffer *head)
1749 {
1750         const bool is_delete = head->w.is_delete;
1751         struct tomoyo_acl_param param = {
1752                 .ns = head->w.ns,
1753                 .is_delete = is_delete,
1754                 .data = head->write_buf,
1755         };
1756         u8 i;
1757 
1758         if (tomoyo_str_starts(&param.data, "aggregator "))
1759                 return tomoyo_write_aggregator(&param);
1760         for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++)
1761                 if (tomoyo_str_starts(&param.data, tomoyo_transition_type[i]))
1762                         return tomoyo_write_transition_control(&param, i);
1763         for (i = 0; i < TOMOYO_MAX_GROUP; i++)
1764                 if (tomoyo_str_starts(&param.data, tomoyo_group_name[i]))
1765                         return tomoyo_write_group(&param, i);
1766         if (tomoyo_str_starts(&param.data, "acl_group ")) {
1767                 unsigned int group;
1768                 char *data;
1769 
1770                 group = simple_strtoul(param.data, &data, 10);
1771                 if (group < TOMOYO_MAX_ACL_GROUPS && *data++ == ' ')
1772                         return tomoyo_write_domain2
1773                                 (head->w.ns, &head->w.ns->acl_group[group],
1774                                  data, is_delete);
1775         }
1776         return -EINVAL;
1777 }
1778 
1779 /**
1780  * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list.
1781  *
1782  * @head: Pointer to "struct tomoyo_io_buffer".
1783  * @idx:  Index number.
1784  *
1785  * Returns true on success, false otherwise.
1786  *
1787  * Caller holds tomoyo_read_lock().
1788  */
1789 static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
1790 {
1791         struct tomoyo_policy_namespace *ns =
1792                 container_of(head->r.ns, typeof(*ns), namespace_list);
1793         struct list_head *list = &ns->group_list[idx];
1794 
1795         list_for_each_cookie(head->r.group, list) {
1796                 struct tomoyo_group *group =
1797                         list_entry(head->r.group, typeof(*group), head.list);
1798 
1799                 list_for_each_cookie(head->r.acl, &group->member_list) {
1800                         struct tomoyo_acl_head *ptr =
1801                                 list_entry(head->r.acl, typeof(*ptr), list);
1802 
1803                         if (ptr->is_deleted)
1804                                 continue;
1805                         if (!tomoyo_flush(head))
1806                                 return false;
1807                         tomoyo_print_namespace(head);
1808                         tomoyo_set_string(head, tomoyo_group_name[idx]);
1809                         tomoyo_set_string(head, group->group_name->name);
1810                         if (idx == TOMOYO_PATH_GROUP) {
1811                                 tomoyo_set_space(head);
1812                                 tomoyo_set_string(head, container_of
1813                                                (ptr, struct tomoyo_path_group,
1814                                                 head)->member_name->name);
1815                         } else if (idx == TOMOYO_NUMBER_GROUP) {
1816                                 tomoyo_print_number_union(head, &container_of
1817                                                           (ptr,
1818                                                    struct tomoyo_number_group,
1819                                                            head)->number);
1820                         } else if (idx == TOMOYO_ADDRESS_GROUP) {
1821                                 char buffer[128];
1822                                 struct tomoyo_address_group *member =
1823                                         container_of(ptr, typeof(*member),
1824                                                      head);
1825 
1826                                 tomoyo_print_ip(buffer, sizeof(buffer),
1827                                                 &member->address);
1828                                 tomoyo_io_printf(head, " %s", buffer);
1829                         }
1830                         tomoyo_set_lf(head);
1831                 }
1832                 head->r.acl = NULL;
1833         }
1834         head->r.group = NULL;
1835         return true;
1836 }
1837 
1838 /**
1839  * tomoyo_read_policy - Read "struct tomoyo_..._entry" list.
1840  *
1841  * @head: Pointer to "struct tomoyo_io_buffer".
1842  * @idx:  Index number.
1843  *
1844  * Returns true on success, false otherwise.
1845  *
1846  * Caller holds tomoyo_read_lock().
1847  */
1848 static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
1849 {
1850         struct tomoyo_policy_namespace *ns =
1851                 container_of(head->r.ns, typeof(*ns), namespace_list);
1852         struct list_head *list = &ns->policy_list[idx];
1853 
1854         list_for_each_cookie(head->r.acl, list) {
1855                 struct tomoyo_acl_head *acl =
1856                         container_of(head->r.acl, typeof(*acl), list);
1857                 if (acl->is_deleted)
1858                         continue;
1859                 if (!tomoyo_flush(head))
1860                         return false;
1861                 switch (idx) {
1862                 case TOMOYO_ID_TRANSITION_CONTROL:
1863                         {
1864                                 struct tomoyo_transition_control *ptr =
1865                                         container_of(acl, typeof(*ptr), head);
1866 
1867                                 tomoyo_print_namespace(head);
1868                                 tomoyo_set_string(head, tomoyo_transition_type
1869                                                   [ptr->type]);
1870                                 tomoyo_set_string(head, ptr->program ?
1871                                                   ptr->program->name : "any");
1872                                 tomoyo_set_string(head, " from ");
1873                                 tomoyo_set_string(head, ptr->domainname ?
1874                                                   ptr->domainname->name :
1875                                                   "any");
1876                         }
1877                         break;
1878                 case TOMOYO_ID_AGGREGATOR:
1879                         {
1880                                 struct tomoyo_aggregator *ptr =
1881                                         container_of(acl, typeof(*ptr), head);
1882 
1883                                 tomoyo_print_namespace(head);
1884                                 tomoyo_set_string(head, "aggregator ");
1885                                 tomoyo_set_string(head,
1886                                                   ptr->original_name->name);
1887                                 tomoyo_set_space(head);
1888                                 tomoyo_set_string(head,
1889                                                ptr->aggregated_name->name);
1890                         }
1891                         break;
1892                 default:
1893                         continue;
1894                 }
1895                 tomoyo_set_lf(head);
1896         }
1897         head->r.acl = NULL;
1898         return true;
1899 }
1900 
1901 /**
1902  * tomoyo_read_exception - Read exception policy.
1903  *
1904  * @head: Pointer to "struct tomoyo_io_buffer".
1905  *
1906  * Caller holds tomoyo_read_lock().
1907  */
1908 static void tomoyo_read_exception(struct tomoyo_io_buffer *head)
1909 {
1910         struct tomoyo_policy_namespace *ns =
1911                 container_of(head->r.ns, typeof(*ns), namespace_list);
1912 
1913         if (head->r.eof)
1914                 return;
1915         while (head->r.step < TOMOYO_MAX_POLICY &&
1916                tomoyo_read_policy(head, head->r.step))
1917                 head->r.step++;
1918         if (head->r.step < TOMOYO_MAX_POLICY)
1919                 return;
1920         while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
1921                tomoyo_read_group(head, head->r.step - TOMOYO_MAX_POLICY))
1922                 head->r.step++;
1923         if (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
1924                 return;
1925         while (head->r.step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP
1926                + TOMOYO_MAX_ACL_GROUPS) {
1927                 head->r.acl_group_index = head->r.step - TOMOYO_MAX_POLICY
1928                         - TOMOYO_MAX_GROUP;
1929                 if (!tomoyo_read_domain2(head, &ns->acl_group
1930                                          [head->r.acl_group_index]))
1931                         return;
1932                 head->r.step++;
1933         }
1934         head->r.eof = true;
1935 }
1936 
1937 /* Wait queue for kernel -> userspace notification. */
1938 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_query_wait);
1939 /* Wait queue for userspace -> kernel notification. */
1940 static DECLARE_WAIT_QUEUE_HEAD(tomoyo_answer_wait);
1941 
1942 /* Structure for query. */
1943 struct tomoyo_query {
1944         struct list_head list;
1945         struct tomoyo_domain_info *domain;
1946         char *query;
1947         size_t query_len;
1948         unsigned int serial;
1949         u8 timer;
1950         u8 answer;
1951         u8 retry;
1952 };
1953 
1954 /* The list for "struct tomoyo_query". */
1955 static LIST_HEAD(tomoyo_query_list);
1956 
1957 /* Lock for manipulating tomoyo_query_list. */
1958 static DEFINE_SPINLOCK(tomoyo_query_list_lock);
1959 
1960 /*
1961  * Number of "struct file" referring /sys/kernel/security/tomoyo/query
1962  * interface.
1963  */
1964 static atomic_t tomoyo_query_observers = ATOMIC_INIT(0);
1965 
1966 /**
1967  * tomoyo_truncate - Truncate a line.
1968  *
1969  * @str: String to truncate.
1970  *
1971  * Returns length of truncated @str.
1972  */
1973 static int tomoyo_truncate(char *str)
1974 {
1975         char *start = str;
1976 
1977         while (*(unsigned char *) str > (unsigned char) ' ')
1978                 str++;
1979         *str = '\0';
1980         return strlen(start) + 1;
1981 }
1982 
1983 /**
1984  * tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
1985  *
1986  * @domain: Pointer to "struct tomoyo_domain_info".
1987  * @header: Lines containing ACL.
1988  *
1989  * Returns nothing.
1990  */
1991 static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
1992 {
1993         char *buffer;
1994         char *realpath = NULL;
1995         char *argv0 = NULL;
1996         char *symlink = NULL;
1997         char *cp = strchr(header, '\n');
1998         int len;
1999 
2000         if (!cp)
2001                 return;
2002         cp = strchr(cp + 1, '\n');
2003         if (!cp)
2004                 return;
2005         *cp++ = '\0';
2006         len = strlen(cp) + 1;
2007         /* strstr() will return NULL if ordering is wrong. */
2008         if (*cp == 'f') {
2009                 argv0 = strstr(header, " argv[]={ \"");
2010                 if (argv0) {
2011                         argv0 += 10;
2012                         len += tomoyo_truncate(argv0) + 14;
2013                 }
2014                 realpath = strstr(header, " exec={ realpath=\"");
2015                 if (realpath) {
2016                         realpath += 8;
2017                         len += tomoyo_truncate(realpath) + 6;
2018                 }
2019                 symlink = strstr(header, " symlink.target=\"");
2020                 if (symlink)
2021                         len += tomoyo_truncate(symlink + 1) + 1;
2022         }
2023         buffer = kmalloc(len, GFP_NOFS);
2024         if (!buffer)
2025                 return;
2026         snprintf(buffer, len - 1, "%s", cp);
2027         if (realpath)
2028                 tomoyo_addprintf(buffer, len, " exec.%s", realpath);
2029         if (argv0)
2030                 tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
2031         if (symlink)
2032                 tomoyo_addprintf(buffer, len, "%s", symlink);
2033         tomoyo_normalize_line(buffer);
2034         if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
2035                                   false))
2036                 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2037         kfree(buffer);
2038 }
2039 
2040 /**
2041  * tomoyo_supervisor - Ask for the supervisor's decision.
2042  *
2043  * @r:   Pointer to "struct tomoyo_request_info".
2044  * @fmt: The printf()'s format string, followed by parameters.
2045  *
2046  * Returns 0 if the supervisor decided to permit the access request which
2047  * violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
2048  * supervisor decided to retry the access request which violated the policy in
2049  * enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2050  */
2051 int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
2052 {
2053         va_list args;
2054         int error;
2055         int len;
2056         static unsigned int tomoyo_serial;
2057         struct tomoyo_query entry = { };
2058         bool quota_exceeded = false;
2059 
2060         va_start(args, fmt);
2061         len = vsnprintf(NULL, 0, fmt, args) + 1;
2062         va_end(args);
2063         /* Write /sys/kernel/security/tomoyo/audit. */
2064         va_start(args, fmt);
2065         tomoyo_write_log2(r, len, fmt, args);
2066         va_end(args);
2067         /* Nothing more to do if granted. */
2068         if (r->granted)
2069                 return 0;
2070         if (r->mode)
2071                 tomoyo_update_stat(r->mode);
2072         switch (r->mode) {
2073         case TOMOYO_CONFIG_ENFORCING:
2074                 error = -EPERM;
2075                 if (atomic_read(&tomoyo_query_observers))
2076                         break;
2077                 goto out;
2078         case TOMOYO_CONFIG_LEARNING:
2079                 error = 0;
2080                 /* Check max_learning_entry parameter. */
2081                 if (tomoyo_domain_quota_is_ok(r))
2082                         break;
2083                 fallthrough;
2084         default:
2085                 return 0;
2086         }
2087         /* Get message. */
2088         va_start(args, fmt);
2089         entry.query = tomoyo_init_log(r, len, fmt, args);
2090         va_end(args);
2091         if (!entry.query)
2092                 goto out;
2093         entry.query_len = strlen(entry.query) + 1;
2094         if (!error) {
2095                 tomoyo_add_entry(r->domain, entry.query);
2096                 goto out;
2097         }
2098         len = kmalloc_size_roundup(entry.query_len);
2099         entry.domain = r->domain;
2100         spin_lock(&tomoyo_query_list_lock);
2101         if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
2102             tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
2103             >= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
2104                 quota_exceeded = true;
2105         } else {
2106                 entry.serial = tomoyo_serial++;
2107                 entry.retry = r->retry;
2108                 tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
2109                 list_add_tail(&entry.list, &tomoyo_query_list);
2110         }
2111         spin_unlock(&tomoyo_query_list_lock);
2112         if (quota_exceeded)
2113                 goto out;
2114         /* Give 10 seconds for supervisor's opinion. */
2115         while (entry.timer < 10) {
2116                 wake_up_all(&tomoyo_query_wait);
2117                 if (wait_event_interruptible_timeout
2118                     (tomoyo_answer_wait, entry.answer ||
2119                      !atomic_read(&tomoyo_query_observers), HZ))
2120                         break;
2121                 entry.timer++;
2122         }
2123         spin_lock(&tomoyo_query_list_lock);
2124         list_del(&entry.list);
2125         tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
2126         spin_unlock(&tomoyo_query_list_lock);
2127         switch (entry.answer) {
2128         case 3: /* Asked to retry by administrator. */
2129                 error = TOMOYO_RETRY_REQUEST;
2130                 r->retry++;
2131                 break;
2132         case 1:
2133                 /* Granted by administrator. */
2134                 error = 0;
2135                 break;
2136         default:
2137                 /* Timed out or rejected by administrator. */
2138                 break;
2139         }
2140 out:
2141         kfree(entry.query);
2142         return error;
2143 }
2144 
2145 /**
2146  * tomoyo_find_domain_by_qid - Get domain by query id.
2147  *
2148  * @serial: Query ID assigned by tomoyo_supervisor().
2149  *
2150  * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
2151  */
2152 static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
2153 (unsigned int serial)
2154 {
2155         struct tomoyo_query *ptr;
2156         struct tomoyo_domain_info *domain = NULL;
2157 
2158         spin_lock(&tomoyo_query_list_lock);
2159         list_for_each_entry(ptr, &tomoyo_query_list, list) {
2160                 if (ptr->serial != serial)
2161                         continue;
2162                 domain = ptr->domain;
2163                 break;
2164         }
2165         spin_unlock(&tomoyo_query_list_lock);
2166         return domain;
2167 }
2168 
2169 /**
2170  * tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
2171  *
2172  * @file: Pointer to "struct file".
2173  * @wait: Pointer to "poll_table".
2174  *
2175  * Returns EPOLLIN | EPOLLRDNORM when ready to read, 0 otherwise.
2176  *
2177  * Waits for access requests which violated policy in enforcing mode.
2178  */
2179 static __poll_t tomoyo_poll_query(struct file *file, poll_table *wait)
2180 {
2181         if (!list_empty(&tomoyo_query_list))
2182                 return EPOLLIN | EPOLLRDNORM;
2183         poll_wait(file, &tomoyo_query_wait, wait);
2184         if (!list_empty(&tomoyo_query_list))
2185                 return EPOLLIN | EPOLLRDNORM;
2186         return 0;
2187 }
2188 
2189 /**
2190  * tomoyo_read_query - Read access requests which violated policy in enforcing mode.
2191  *
2192  * @head: Pointer to "struct tomoyo_io_buffer".
2193  */
2194 static void tomoyo_read_query(struct tomoyo_io_buffer *head)
2195 {
2196         struct list_head *tmp;
2197         unsigned int pos = 0;
2198         size_t len = 0;
2199         char *buf;
2200 
2201         if (head->r.w_pos)
2202                 return;
2203         kfree(head->read_buf);
2204         head->read_buf = NULL;
2205         spin_lock(&tomoyo_query_list_lock);
2206         list_for_each(tmp, &tomoyo_query_list) {
2207                 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2208 
2209                 if (pos++ != head->r.query_index)
2210                         continue;
2211                 len = ptr->query_len;
2212                 break;
2213         }
2214         spin_unlock(&tomoyo_query_list_lock);
2215         if (!len) {
2216                 head->r.query_index = 0;
2217                 return;
2218         }
2219         buf = kzalloc(len + 32, GFP_NOFS);
2220         if (!buf)
2221                 return;
2222         pos = 0;
2223         spin_lock(&tomoyo_query_list_lock);
2224         list_for_each(tmp, &tomoyo_query_list) {
2225                 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2226 
2227                 if (pos++ != head->r.query_index)
2228                         continue;
2229                 /*
2230                  * Some query can be skipped because tomoyo_query_list
2231                  * can change, but I don't care.
2232                  */
2233                 if (len == ptr->query_len)
2234                         snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
2235                                  ptr->retry, ptr->query);
2236                 break;
2237         }
2238         spin_unlock(&tomoyo_query_list_lock);
2239         if (buf[0]) {
2240                 head->read_buf = buf;
2241                 head->r.w[head->r.w_pos++] = buf;
2242                 head->r.query_index++;
2243         } else {
2244                 kfree(buf);
2245         }
2246 }
2247 
2248 /**
2249  * tomoyo_write_answer - Write the supervisor's decision.
2250  *
2251  * @head: Pointer to "struct tomoyo_io_buffer".
2252  *
2253  * Returns 0 on success, -EINVAL otherwise.
2254  */
2255 static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2256 {
2257         char *data = head->write_buf;
2258         struct list_head *tmp;
2259         unsigned int serial;
2260         unsigned int answer;
2261 
2262         spin_lock(&tomoyo_query_list_lock);
2263         list_for_each(tmp, &tomoyo_query_list) {
2264                 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2265 
2266                 ptr->timer = 0;
2267         }
2268         spin_unlock(&tomoyo_query_list_lock);
2269         if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2270                 return -EINVAL;
2271         spin_lock(&tomoyo_query_list_lock);
2272         list_for_each(tmp, &tomoyo_query_list) {
2273                 struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2274 
2275                 if (ptr->serial != serial)
2276                         continue;
2277                 ptr->answer = answer;
2278                 /* Remove from tomoyo_query_list. */
2279                 if (ptr->answer)
2280                         list_del_init(&ptr->list);
2281                 break;
2282         }
2283         spin_unlock(&tomoyo_query_list_lock);
2284         return 0;
2285 }
2286 
2287 /**
2288  * tomoyo_read_version: Get version.
2289  *
2290  * @head: Pointer to "struct tomoyo_io_buffer".
2291  *
2292  * Returns version information.
2293  */
2294 static void tomoyo_read_version(struct tomoyo_io_buffer *head)
2295 {
2296         if (!head->r.eof) {
2297                 tomoyo_io_printf(head, "2.6.0");
2298                 head->r.eof = true;
2299         }
2300 }
2301 
2302 /* String table for /sys/kernel/security/tomoyo/stat interface. */
2303 static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
2304         [TOMOYO_STAT_POLICY_UPDATES]    = "update:",
2305         [TOMOYO_STAT_POLICY_LEARNING]   = "violation in learning mode:",
2306         [TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
2307         [TOMOYO_STAT_POLICY_ENFORCING]  = "violation in enforcing mode:",
2308 };
2309 
2310 /* String table for /sys/kernel/security/tomoyo/stat interface. */
2311 static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
2312         [TOMOYO_MEMORY_POLICY] = "policy:",
2313         [TOMOYO_MEMORY_AUDIT]  = "audit log:",
2314         [TOMOYO_MEMORY_QUERY]  = "query message:",
2315 };
2316 
2317 /* Counter for number of updates. */
2318 static atomic_t tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
2319 /* Timestamp counter for last updated. */
2320 static time64_t tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
2321 
2322 /**
2323  * tomoyo_update_stat - Update statistic counters.
2324  *
2325  * @index: Index for policy type.
2326  *
2327  * Returns nothing.
2328  */
2329 void tomoyo_update_stat(const u8 index)
2330 {
2331         atomic_inc(&tomoyo_stat_updated[index]);
2332         tomoyo_stat_modified[index] = ktime_get_real_seconds();
2333 }
2334 
2335 /**
2336  * tomoyo_read_stat - Read statistic data.
2337  *
2338  * @head: Pointer to "struct tomoyo_io_buffer".
2339  *
2340  * Returns nothing.
2341  */
2342 static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
2343 {
2344         u8 i;
2345         unsigned int total = 0;
2346 
2347         if (head->r.eof)
2348                 return;
2349         for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
2350                 tomoyo_io_printf(head, "Policy %-30s %10u",
2351                                  tomoyo_policy_headers[i],
2352                                  atomic_read(&tomoyo_stat_updated[i]));
2353                 if (tomoyo_stat_modified[i]) {
2354                         struct tomoyo_time stamp;
2355 
2356                         tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
2357                         tomoyo_io_printf(head, " (Last: %04u/%02u/%02u %02u:%02u:%02u)",
2358                                          stamp.year, stamp.month, stamp.day,
2359                                          stamp.hour, stamp.min, stamp.sec);
2360                 }
2361                 tomoyo_set_lf(head);
2362         }
2363         for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
2364                 unsigned int used = tomoyo_memory_used[i];
2365 
2366                 total += used;
2367                 tomoyo_io_printf(head, "Memory used by %-22s %10u",
2368                                  tomoyo_memory_headers[i], used);
2369                 used = tomoyo_memory_quota[i];
2370                 if (used)
2371                         tomoyo_io_printf(head, " (Quota: %10u)", used);
2372                 tomoyo_set_lf(head);
2373         }
2374         tomoyo_io_printf(head, "Total memory used:                    %10u\n",
2375                          total);
2376         head->r.eof = true;
2377 }
2378 
2379 /**
2380  * tomoyo_write_stat - Set memory quota.
2381  *
2382  * @head: Pointer to "struct tomoyo_io_buffer".
2383  *
2384  * Returns 0.
2385  */
2386 static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
2387 {
2388         char *data = head->write_buf;
2389         u8 i;
2390 
2391         if (tomoyo_str_starts(&data, "Memory used by "))
2392                 for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
2393                         if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
2394                                 sscanf(data, "%u", &tomoyo_memory_quota[i]);
2395         return 0;
2396 }
2397 
2398 /**
2399  * tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
2400  *
2401  * @type: Type of interface.
2402  * @file: Pointer to "struct file".
2403  *
2404  * Returns 0 on success, negative value otherwise.
2405  */
2406 int tomoyo_open_control(const u8 type, struct file *file)
2407 {
2408         struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
2409 
2410         if (!head)
2411                 return -ENOMEM;
2412         mutex_init(&head->io_sem);
2413         head->type = type;
2414         switch (type) {
2415         case TOMOYO_DOMAINPOLICY:
2416                 /* /sys/kernel/security/tomoyo/domain_policy */
2417                 head->write = tomoyo_write_domain;
2418                 head->read = tomoyo_read_domain;
2419                 break;
2420         case TOMOYO_EXCEPTIONPOLICY:
2421                 /* /sys/kernel/security/tomoyo/exception_policy */
2422                 head->write = tomoyo_write_exception;
2423                 head->read = tomoyo_read_exception;
2424                 break;
2425         case TOMOYO_AUDIT:
2426                 /* /sys/kernel/security/tomoyo/audit */
2427                 head->poll = tomoyo_poll_log;
2428                 head->read = tomoyo_read_log;
2429                 break;
2430         case TOMOYO_PROCESS_STATUS:
2431                 /* /sys/kernel/security/tomoyo/.process_status */
2432                 head->write = tomoyo_write_pid;
2433                 head->read = tomoyo_read_pid;
2434                 break;
2435         case TOMOYO_VERSION:
2436                 /* /sys/kernel/security/tomoyo/version */
2437                 head->read = tomoyo_read_version;
2438                 head->readbuf_size = 128;
2439                 break;
2440         case TOMOYO_STAT:
2441                 /* /sys/kernel/security/tomoyo/stat */
2442                 head->write = tomoyo_write_stat;
2443                 head->read = tomoyo_read_stat;
2444                 head->readbuf_size = 1024;
2445                 break;
2446         case TOMOYO_PROFILE:
2447                 /* /sys/kernel/security/tomoyo/profile */
2448                 head->write = tomoyo_write_profile;
2449                 head->read = tomoyo_read_profile;
2450                 break;
2451         case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
2452                 head->poll = tomoyo_poll_query;
2453                 head->write = tomoyo_write_answer;
2454                 head->read = tomoyo_read_query;
2455                 break;
2456         case TOMOYO_MANAGER:
2457                 /* /sys/kernel/security/tomoyo/manager */
2458                 head->write = tomoyo_write_manager;
2459                 head->read = tomoyo_read_manager;
2460                 break;
2461         }
2462         if (!(file->f_mode & FMODE_READ)) {
2463                 /*
2464                  * No need to allocate read_buf since it is not opened
2465                  * for reading.
2466                  */
2467                 head->read = NULL;
2468                 head->poll = NULL;
2469         } else if (!head->poll) {
2470                 /* Don't allocate read_buf for poll() access. */
2471                 if (!head->readbuf_size)
2472                         head->readbuf_size = 4096 * 2;
2473                 head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
2474                 if (!head->read_buf) {
2475                         kfree(head);
2476                         return -ENOMEM;
2477                 }
2478         }
2479         if (!(file->f_mode & FMODE_WRITE)) {
2480                 /*
2481                  * No need to allocate write_buf since it is not opened
2482                  * for writing.
2483                  */
2484                 head->write = NULL;
2485         } else if (head->write) {
2486                 head->writebuf_size = 4096 * 2;
2487                 head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
2488                 if (!head->write_buf) {
2489                         kfree(head->read_buf);
2490                         kfree(head);
2491                         return -ENOMEM;
2492                 }
2493         }
2494         /*
2495          * If the file is /sys/kernel/security/tomoyo/query , increment the
2496          * observer counter.
2497          * The obserber counter is used by tomoyo_supervisor() to see if
2498          * there is some process monitoring /sys/kernel/security/tomoyo/query.
2499          */
2500         if (type == TOMOYO_QUERY)
2501                 atomic_inc(&tomoyo_query_observers);
2502         file->private_data = head;
2503         tomoyo_notify_gc(head, true);
2504         return 0;
2505 }
2506 
2507 /**
2508  * tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2509  *
2510  * @file: Pointer to "struct file".
2511  * @wait: Pointer to "poll_table". Maybe NULL.
2512  *
2513  * Returns EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM if ready to read/write,
2514  * EPOLLOUT | EPOLLWRNORM otherwise.
2515  */
2516 __poll_t tomoyo_poll_control(struct file *file, poll_table *wait)
2517 {
2518         struct tomoyo_io_buffer *head = file->private_data;
2519 
2520         if (head->poll)
2521                 return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM;
2522         return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM;
2523 }
2524 
2525 /**
2526  * tomoyo_set_namespace_cursor - Set namespace to read.
2527  *
2528  * @head: Pointer to "struct tomoyo_io_buffer".
2529  *
2530  * Returns nothing.
2531  */
2532 static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
2533 {
2534         struct list_head *ns;
2535 
2536         if (head->type != TOMOYO_EXCEPTIONPOLICY &&
2537             head->type != TOMOYO_PROFILE)
2538                 return;
2539         /*
2540          * If this is the first read, or reading previous namespace finished
2541          * and has more namespaces to read, update the namespace cursor.
2542          */
2543         ns = head->r.ns;
2544         if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
2545                 /* Clearing is OK because tomoyo_flush() returned true. */
2546                 memset(&head->r, 0, sizeof(head->r));
2547                 head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
2548         }
2549 }
2550 
2551 /**
2552  * tomoyo_has_more_namespace - Check for unread namespaces.
2553  *
2554  * @head: Pointer to "struct tomoyo_io_buffer".
2555  *
2556  * Returns true if we have more entries to print, false otherwise.
2557  */
2558 static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2559 {
2560         return (head->type == TOMOYO_EXCEPTIONPOLICY ||
2561                 head->type == TOMOYO_PROFILE) && head->r.eof &&
2562                 head->r.ns->next != &tomoyo_namespace_list;
2563 }
2564 
2565 /**
2566  * tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
2567  *
2568  * @head:       Pointer to "struct tomoyo_io_buffer".
2569  * @buffer:     Pointer to buffer to write to.
2570  * @buffer_len: Size of @buffer.
2571  *
2572  * Returns bytes read on success, negative value otherwise.
2573  */
2574 ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2575                             const int buffer_len)
2576 {
2577         int len;
2578         int idx;
2579 
2580         if (!head->read)
2581                 return -EINVAL;
2582         if (mutex_lock_interruptible(&head->io_sem))
2583                 return -EINTR;
2584         head->read_user_buf = buffer;
2585         head->read_user_buf_avail = buffer_len;
2586         idx = tomoyo_read_lock();
2587         if (tomoyo_flush(head))
2588                 /* Call the policy handler. */
2589                 do {
2590                         tomoyo_set_namespace_cursor(head);
2591                         head->read(head);
2592                 } while (tomoyo_flush(head) &&
2593                          tomoyo_has_more_namespace(head));
2594         tomoyo_read_unlock(idx);
2595         len = head->read_user_buf - buffer;
2596         mutex_unlock(&head->io_sem);
2597         return len;
2598 }
2599 
2600 /**
2601  * tomoyo_parse_policy - Parse a policy line.
2602  *
2603  * @head: Pointer to "struct tomoyo_io_buffer".
2604  * @line: Line to parse.
2605  *
2606  * Returns 0 on success, negative value otherwise.
2607  *
2608  * Caller holds tomoyo_read_lock().
2609  */
2610 static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2611 {
2612         /* Delete request? */
2613         head->w.is_delete = !strncmp(line, "delete ", 7);
2614         if (head->w.is_delete)
2615                 memmove(line, line + 7, strlen(line + 7) + 1);
2616         /* Selecting namespace to update. */
2617         if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2618             head->type == TOMOYO_PROFILE) {
2619                 if (*line == '<') {
2620                         char *cp = strchr(line, ' ');
2621 
2622                         if (cp) {
2623                                 *cp++ = '\0';
2624                                 head->w.ns = tomoyo_assign_namespace(line);
2625                                 memmove(line, cp, strlen(cp) + 1);
2626                         } else
2627                                 head->w.ns = NULL;
2628                 } else
2629                         head->w.ns = &tomoyo_kernel_namespace;
2630                 /* Don't allow updating if namespace is invalid. */
2631                 if (!head->w.ns)
2632                         return -ENOENT;
2633         }
2634         /* Do the update. */
2635         return head->write(head);
2636 }
2637 
2638 /**
2639  * tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
2640  *
2641  * @head:       Pointer to "struct tomoyo_io_buffer".
2642  * @buffer:     Pointer to buffer to read from.
2643  * @buffer_len: Size of @buffer.
2644  *
2645  * Returns @buffer_len on success, negative value otherwise.
2646  */
2647 ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
2648                              const char __user *buffer, const int buffer_len)
2649 {
2650         int error = buffer_len;
2651         size_t avail_len = buffer_len;
2652         char *cp0;
2653         int idx;
2654 
2655         if (!head->write)
2656                 return -EINVAL;
2657         if (mutex_lock_interruptible(&head->io_sem))
2658                 return -EINTR;
2659         cp0 = head->write_buf;
2660         head->read_user_buf_avail = 0;
2661         idx = tomoyo_read_lock();
2662         /* Read a line and dispatch it to the policy handler. */
2663         while (avail_len > 0) {
2664                 char c;
2665 
2666                 if (head->w.avail >= head->writebuf_size - 1) {
2667                         const int len = head->writebuf_size * 2;
2668                         char *cp = kzalloc(len, GFP_NOFS);
2669 
2670                         if (!cp) {
2671                                 error = -ENOMEM;
2672                                 break;
2673                         }
2674                         memmove(cp, cp0, head->w.avail);
2675                         kfree(cp0);
2676                         head->write_buf = cp;
2677                         cp0 = cp;
2678                         head->writebuf_size = len;
2679                 }
2680                 if (get_user(c, buffer)) {
2681                         error = -EFAULT;
2682                         break;
2683                 }
2684                 buffer++;
2685                 avail_len--;
2686                 cp0[head->w.avail++] = c;
2687                 if (c != '\n')
2688                         continue;
2689                 cp0[head->w.avail - 1] = '\0';
2690                 head->w.avail = 0;
2691                 tomoyo_normalize_line(cp0);
2692                 if (!strcmp(cp0, "reset")) {
2693                         head->w.ns = &tomoyo_kernel_namespace;
2694                         head->w.domain = NULL;
2695                         memset(&head->r, 0, sizeof(head->r));
2696                         continue;
2697                 }
2698                 /* Don't allow updating policies by non manager programs. */
2699                 switch (head->type) {
2700                 case TOMOYO_PROCESS_STATUS:
2701                         /* This does not write anything. */
2702                         break;
2703                 case TOMOYO_DOMAINPOLICY:
2704                         if (tomoyo_select_domain(head, cp0))
2705                                 continue;
2706                         fallthrough;
2707                 case TOMOYO_EXCEPTIONPOLICY:
2708                         if (!strcmp(cp0, "select transition_only")) {
2709                                 head->r.print_transition_related_only = true;
2710                                 continue;
2711                         }
2712                         fallthrough;
2713                 default:
2714                         if (!tomoyo_manager()) {
2715                                 error = -EPERM;
2716                                 goto out;
2717                         }
2718                 }
2719                 switch (tomoyo_parse_policy(head, cp0)) {
2720                 case -EPERM:
2721                         error = -EPERM;
2722                         goto out;
2723                 case 0:
2724                         switch (head->type) {
2725                         case TOMOYO_DOMAINPOLICY:
2726                         case TOMOYO_EXCEPTIONPOLICY:
2727                         case TOMOYO_STAT:
2728                         case TOMOYO_PROFILE:
2729                         case TOMOYO_MANAGER:
2730                                 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2731                                 break;
2732                         default:
2733                                 break;
2734                         }
2735                         break;
2736                 }
2737         }
2738 out:
2739         tomoyo_read_unlock(idx);
2740         mutex_unlock(&head->io_sem);
2741         return error;
2742 }
2743 
2744 /**
2745  * tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2746  *
2747  * @head: Pointer to "struct tomoyo_io_buffer".
2748  */
2749 void tomoyo_close_control(struct tomoyo_io_buffer *head)
2750 {
2751         /*
2752          * If the file is /sys/kernel/security/tomoyo/query , decrement the
2753          * observer counter.
2754          */
2755         if (head->type == TOMOYO_QUERY &&
2756             atomic_dec_and_test(&tomoyo_query_observers))
2757                 wake_up_all(&tomoyo_answer_wait);
2758         tomoyo_notify_gc(head, false);
2759 }
2760 
2761 /**
2762  * tomoyo_check_profile - Check all profiles currently assigned to domains are defined.
2763  */
2764 void tomoyo_check_profile(void)
2765 {
2766         struct tomoyo_domain_info *domain;
2767         const int idx = tomoyo_read_lock();
2768 
2769         tomoyo_policy_loaded = true;
2770         pr_info("TOMOYO: 2.6.0\n");
2771         list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
2772                                 srcu_read_lock_held(&tomoyo_ss)) {
2773                 const u8 profile = domain->profile;
2774                 struct tomoyo_policy_namespace *ns = domain->ns;
2775 
2776                 if (ns->profile_version == 20110903) {
2777                         pr_info_once("Converting profile version from %u to %u.\n",
2778                                      20110903, 20150505);
2779                         ns->profile_version = 20150505;
2780                 }
2781                 if (ns->profile_version != 20150505)
2782                         pr_err("Profile version %u is not supported.\n",
2783                                ns->profile_version);
2784                 else if (!ns->profile_ptr[profile])
2785                         pr_err("Profile %u (used by '%s') is not defined.\n",
2786                                profile, domain->domainname->name);
2787                 else
2788                         continue;
2789                 pr_err("Userland tools for TOMOYO 2.6 must be installed and policy must be initialized.\n");
2790                 pr_err("Please see https://tomoyo.sourceforge.net/2.6/ for more information.\n");
2791                 panic("STOP!");
2792         }
2793         tomoyo_read_unlock(idx);
2794         pr_info("Mandatory Access Control activated.\n");
2795 }
2796 
2797 /**
2798  * tomoyo_load_builtin_policy - Load built-in policy.
2799  *
2800  * Returns nothing.
2801  */
2802 void __init tomoyo_load_builtin_policy(void)
2803 {
2804 #ifdef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
2805         static char tomoyo_builtin_profile[] __initdata =
2806                 "PROFILE_VERSION=20150505\n"
2807                 "0-CONFIG={ mode=learning grant_log=no reject_log=yes }\n";
2808         static char tomoyo_builtin_exception_policy[] __initdata =
2809                 "aggregator proc:/self/exe /proc/self/exe\n";
2810         static char tomoyo_builtin_domain_policy[] __initdata = "";
2811         static char tomoyo_builtin_manager[] __initdata = "";
2812         static char tomoyo_builtin_stat[] __initdata = "";
2813 #else
2814         /*
2815          * This include file is manually created and contains built-in policy
2816          * named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
2817          * "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
2818          * "tomoyo_builtin_stat" in the form of "static char [] __initdata".
2819          */
2820 #include "builtin-policy.h"
2821 #endif
2822         u8 i;
2823         const int idx = tomoyo_read_lock();
2824 
2825         for (i = 0; i < 5; i++) {
2826                 struct tomoyo_io_buffer head = { };
2827                 char *start = "";
2828 
2829                 switch (i) {
2830                 case 0:
2831                         start = tomoyo_builtin_profile;
2832                         head.type = TOMOYO_PROFILE;
2833                         head.write = tomoyo_write_profile;
2834                         break;
2835                 case 1:
2836                         start = tomoyo_builtin_exception_policy;
2837                         head.type = TOMOYO_EXCEPTIONPOLICY;
2838                         head.write = tomoyo_write_exception;
2839                         break;
2840                 case 2:
2841                         start = tomoyo_builtin_domain_policy;
2842                         head.type = TOMOYO_DOMAINPOLICY;
2843                         head.write = tomoyo_write_domain;
2844                         break;
2845                 case 3:
2846                         start = tomoyo_builtin_manager;
2847                         head.type = TOMOYO_MANAGER;
2848                         head.write = tomoyo_write_manager;
2849                         break;
2850                 case 4:
2851                         start = tomoyo_builtin_stat;
2852                         head.type = TOMOYO_STAT;
2853                         head.write = tomoyo_write_stat;
2854                         break;
2855                 }
2856                 while (1) {
2857                         char *end = strchr(start, '\n');
2858 
2859                         if (!end)
2860                                 break;
2861                         *end = '\0';
2862                         tomoyo_normalize_line(start);
2863                         head.write_buf = start;
2864                         tomoyo_parse_policy(&head, start);
2865                         start = end + 1;
2866                 }
2867         }
2868         tomoyo_read_unlock(idx);
2869 #ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
2870         tomoyo_check_profile();
2871 #endif
2872 }
2873 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php