Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/tomoyo/common.c
26378 views
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_numscan - sscanf() which stores the length of a decimal integer value.
1985
*
1986
* @str: String to scan.
1987
* @head: Leading string that must start with.
1988
* @width: Pointer to "int" for storing length of a decimal integer value after @head.
1989
* @tail: Optional character that must match after a decimal integer value.
1990
*
1991
* Returns whether @str starts with @head and a decimal value follows @head.
1992
*/
1993
static bool tomoyo_numscan(const char *str, const char *head, int *width, const char tail)
1994
{
1995
const char *cp;
1996
const int n = strlen(head);
1997
1998
if (!strncmp(str, head, n)) {
1999
cp = str + n;
2000
while (*cp && *cp >= '0' && *cp <= '9')
2001
cp++;
2002
if (*cp == tail || !tail) {
2003
*width = cp - (str + n);
2004
return *width != 0;
2005
}
2006
}
2007
*width = 0;
2008
return 0;
2009
}
2010
2011
/**
2012
* tomoyo_patternize_path - Make patterns for file path. Used by learning mode.
2013
*
2014
* @buffer: Destination buffer.
2015
* @len: Size of @buffer.
2016
* @entry: Original line.
2017
*
2018
* Returns nothing.
2019
*/
2020
static void tomoyo_patternize_path(char *buffer, const int len, char *entry)
2021
{
2022
int width;
2023
char *cp = entry;
2024
2025
/* Nothing to do if this line is not for "file" related entry. */
2026
if (strncmp(entry, "file ", 5))
2027
goto flush;
2028
/*
2029
* Nothing to do if there is no colon in this line, for this rewriting
2030
* applies to only filesystems where numeric values in the path are volatile.
2031
*/
2032
cp = strchr(entry + 5, ':');
2033
if (!cp) {
2034
cp = entry;
2035
goto flush;
2036
}
2037
/* Flush e.g. "file ioctl" part. */
2038
while (*cp != ' ')
2039
cp--;
2040
*cp++ = '\0';
2041
tomoyo_addprintf(buffer, len, "%s ", entry);
2042
/* e.g. file ioctl pipe:[$INO] $CMD */
2043
if (tomoyo_numscan(cp, "pipe:[", &width, ']')) {
2044
cp += width + 7;
2045
tomoyo_addprintf(buffer, len, "pipe:[\\$]");
2046
goto flush;
2047
}
2048
/* e.g. file ioctl socket:[$INO] $CMD */
2049
if (tomoyo_numscan(cp, "socket:[", &width, ']')) {
2050
cp += width + 9;
2051
tomoyo_addprintf(buffer, len, "socket:[\\$]");
2052
goto flush;
2053
}
2054
if (!strncmp(cp, "proc:/self", 10)) {
2055
/* e.g. file read proc:/self/task/$TID/fdinfo/$FD */
2056
cp += 10;
2057
tomoyo_addprintf(buffer, len, "proc:/self");
2058
} else if (tomoyo_numscan(cp, "proc:/", &width, 0)) {
2059
/* e.g. file read proc:/$PID/task/$TID/fdinfo/$FD */
2060
/*
2061
* Don't patternize $PID part if $PID == 1, for several
2062
* programs access only files in /proc/1/ directory.
2063
*/
2064
cp += width + 6;
2065
if (width == 1 && *(cp - 1) == '1')
2066
tomoyo_addprintf(buffer, len, "proc:/1");
2067
else
2068
tomoyo_addprintf(buffer, len, "proc:/\\$");
2069
} else {
2070
goto flush;
2071
}
2072
/* Patternize $TID part if "/task/" follows. */
2073
if (tomoyo_numscan(cp, "/task/", &width, 0)) {
2074
cp += width + 6;
2075
tomoyo_addprintf(buffer, len, "/task/\\$");
2076
}
2077
/* Patternize $FD part if "/fd/" or "/fdinfo/" follows. */
2078
if (tomoyo_numscan(cp, "/fd/", &width, 0)) {
2079
cp += width + 4;
2080
tomoyo_addprintf(buffer, len, "/fd/\\$");
2081
} else if (tomoyo_numscan(cp, "/fdinfo/", &width, 0)) {
2082
cp += width + 8;
2083
tomoyo_addprintf(buffer, len, "/fdinfo/\\$");
2084
}
2085
flush:
2086
/* Flush remaining part if any. */
2087
if (*cp)
2088
tomoyo_addprintf(buffer, len, "%s", cp);
2089
}
2090
2091
/**
2092
* tomoyo_add_entry - Add an ACL to current thread's domain. Used by learning mode.
2093
*
2094
* @domain: Pointer to "struct tomoyo_domain_info".
2095
* @header: Lines containing ACL.
2096
*
2097
* Returns nothing.
2098
*/
2099
static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
2100
{
2101
char *buffer;
2102
char *realpath = NULL;
2103
char *argv0 = NULL;
2104
char *symlink = NULL;
2105
char *cp = strchr(header, '\n');
2106
int len;
2107
2108
if (!cp)
2109
return;
2110
cp = strchr(cp + 1, '\n');
2111
if (!cp)
2112
return;
2113
*cp++ = '\0';
2114
/* Reserve some space for potentially using patterns. */
2115
len = strlen(cp) + 16;
2116
/* strstr() will return NULL if ordering is wrong. */
2117
if (*cp == 'f') {
2118
argv0 = strstr(header, " argv[]={ \"");
2119
if (argv0) {
2120
argv0 += 10;
2121
len += tomoyo_truncate(argv0) + 14;
2122
}
2123
realpath = strstr(header, " exec={ realpath=\"");
2124
if (realpath) {
2125
realpath += 8;
2126
len += tomoyo_truncate(realpath) + 6;
2127
}
2128
symlink = strstr(header, " symlink.target=\"");
2129
if (symlink)
2130
len += tomoyo_truncate(symlink + 1) + 1;
2131
}
2132
buffer = kmalloc(len, GFP_NOFS | __GFP_ZERO);
2133
if (!buffer)
2134
return;
2135
tomoyo_patternize_path(buffer, len, cp);
2136
if (realpath)
2137
tomoyo_addprintf(buffer, len, " exec.%s", realpath);
2138
if (argv0)
2139
tomoyo_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
2140
if (symlink)
2141
tomoyo_addprintf(buffer, len, "%s", symlink);
2142
tomoyo_normalize_line(buffer);
2143
if (!tomoyo_write_domain2(domain->ns, &domain->acl_info_list, buffer,
2144
false))
2145
tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2146
kfree(buffer);
2147
}
2148
2149
/**
2150
* tomoyo_supervisor - Ask for the supervisor's decision.
2151
*
2152
* @r: Pointer to "struct tomoyo_request_info".
2153
* @fmt: The printf()'s format string, followed by parameters.
2154
*
2155
* Returns 0 if the supervisor decided to permit the access request which
2156
* violated the policy in enforcing mode, TOMOYO_RETRY_REQUEST if the
2157
* supervisor decided to retry the access request which violated the policy in
2158
* enforcing mode, 0 if it is not in enforcing mode, -EPERM otherwise.
2159
*/
2160
int tomoyo_supervisor(struct tomoyo_request_info *r, const char *fmt, ...)
2161
{
2162
va_list args;
2163
int error;
2164
int len;
2165
static unsigned int tomoyo_serial;
2166
struct tomoyo_query entry = { };
2167
bool quota_exceeded = false;
2168
2169
va_start(args, fmt);
2170
len = vsnprintf(NULL, 0, fmt, args) + 1;
2171
va_end(args);
2172
/* Write /sys/kernel/security/tomoyo/audit. */
2173
va_start(args, fmt);
2174
tomoyo_write_log2(r, len, fmt, args);
2175
va_end(args);
2176
/* Nothing more to do if granted. */
2177
if (r->granted)
2178
return 0;
2179
if (r->mode)
2180
tomoyo_update_stat(r->mode);
2181
switch (r->mode) {
2182
case TOMOYO_CONFIG_ENFORCING:
2183
error = -EPERM;
2184
if (atomic_read(&tomoyo_query_observers))
2185
break;
2186
goto out;
2187
case TOMOYO_CONFIG_LEARNING:
2188
error = 0;
2189
/* Check max_learning_entry parameter. */
2190
if (tomoyo_domain_quota_is_ok(r))
2191
break;
2192
fallthrough;
2193
default:
2194
return 0;
2195
}
2196
/* Get message. */
2197
va_start(args, fmt);
2198
entry.query = tomoyo_init_log(r, len, fmt, args);
2199
va_end(args);
2200
if (!entry.query)
2201
goto out;
2202
entry.query_len = strlen(entry.query) + 1;
2203
if (!error) {
2204
tomoyo_add_entry(r->domain, entry.query);
2205
goto out;
2206
}
2207
len = kmalloc_size_roundup(entry.query_len);
2208
entry.domain = r->domain;
2209
spin_lock(&tomoyo_query_list_lock);
2210
if (tomoyo_memory_quota[TOMOYO_MEMORY_QUERY] &&
2211
tomoyo_memory_used[TOMOYO_MEMORY_QUERY] + len
2212
>= tomoyo_memory_quota[TOMOYO_MEMORY_QUERY]) {
2213
quota_exceeded = true;
2214
} else {
2215
entry.serial = tomoyo_serial++;
2216
entry.retry = r->retry;
2217
tomoyo_memory_used[TOMOYO_MEMORY_QUERY] += len;
2218
list_add_tail(&entry.list, &tomoyo_query_list);
2219
}
2220
spin_unlock(&tomoyo_query_list_lock);
2221
if (quota_exceeded)
2222
goto out;
2223
/* Give 10 seconds for supervisor's opinion. */
2224
while (entry.timer < 10) {
2225
wake_up_all(&tomoyo_query_wait);
2226
if (wait_event_interruptible_timeout
2227
(tomoyo_answer_wait, entry.answer ||
2228
!atomic_read(&tomoyo_query_observers), HZ))
2229
break;
2230
entry.timer++;
2231
}
2232
spin_lock(&tomoyo_query_list_lock);
2233
list_del(&entry.list);
2234
tomoyo_memory_used[TOMOYO_MEMORY_QUERY] -= len;
2235
spin_unlock(&tomoyo_query_list_lock);
2236
switch (entry.answer) {
2237
case 3: /* Asked to retry by administrator. */
2238
error = TOMOYO_RETRY_REQUEST;
2239
r->retry++;
2240
break;
2241
case 1:
2242
/* Granted by administrator. */
2243
error = 0;
2244
break;
2245
default:
2246
/* Timed out or rejected by administrator. */
2247
break;
2248
}
2249
out:
2250
kfree(entry.query);
2251
return error;
2252
}
2253
2254
/**
2255
* tomoyo_find_domain_by_qid - Get domain by query id.
2256
*
2257
* @serial: Query ID assigned by tomoyo_supervisor().
2258
*
2259
* Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
2260
*/
2261
static struct tomoyo_domain_info *tomoyo_find_domain_by_qid
2262
(unsigned int serial)
2263
{
2264
struct tomoyo_query *ptr;
2265
struct tomoyo_domain_info *domain = NULL;
2266
2267
spin_lock(&tomoyo_query_list_lock);
2268
list_for_each_entry(ptr, &tomoyo_query_list, list) {
2269
if (ptr->serial != serial)
2270
continue;
2271
domain = ptr->domain;
2272
break;
2273
}
2274
spin_unlock(&tomoyo_query_list_lock);
2275
return domain;
2276
}
2277
2278
/**
2279
* tomoyo_poll_query - poll() for /sys/kernel/security/tomoyo/query.
2280
*
2281
* @file: Pointer to "struct file".
2282
* @wait: Pointer to "poll_table".
2283
*
2284
* Returns EPOLLIN | EPOLLRDNORM when ready to read, 0 otherwise.
2285
*
2286
* Waits for access requests which violated policy in enforcing mode.
2287
*/
2288
static __poll_t tomoyo_poll_query(struct file *file, poll_table *wait)
2289
{
2290
if (!list_empty(&tomoyo_query_list))
2291
return EPOLLIN | EPOLLRDNORM;
2292
poll_wait(file, &tomoyo_query_wait, wait);
2293
if (!list_empty(&tomoyo_query_list))
2294
return EPOLLIN | EPOLLRDNORM;
2295
return 0;
2296
}
2297
2298
/**
2299
* tomoyo_read_query - Read access requests which violated policy in enforcing mode.
2300
*
2301
* @head: Pointer to "struct tomoyo_io_buffer".
2302
*/
2303
static void tomoyo_read_query(struct tomoyo_io_buffer *head)
2304
{
2305
struct list_head *tmp;
2306
unsigned int pos = 0;
2307
size_t len = 0;
2308
char *buf;
2309
2310
if (head->r.w_pos)
2311
return;
2312
kfree(head->read_buf);
2313
head->read_buf = NULL;
2314
spin_lock(&tomoyo_query_list_lock);
2315
list_for_each(tmp, &tomoyo_query_list) {
2316
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2317
2318
if (pos++ != head->r.query_index)
2319
continue;
2320
len = ptr->query_len;
2321
break;
2322
}
2323
spin_unlock(&tomoyo_query_list_lock);
2324
if (!len) {
2325
head->r.query_index = 0;
2326
return;
2327
}
2328
buf = kzalloc(len + 32, GFP_NOFS);
2329
if (!buf)
2330
return;
2331
pos = 0;
2332
spin_lock(&tomoyo_query_list_lock);
2333
list_for_each(tmp, &tomoyo_query_list) {
2334
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2335
2336
if (pos++ != head->r.query_index)
2337
continue;
2338
/*
2339
* Some query can be skipped because tomoyo_query_list
2340
* can change, but I don't care.
2341
*/
2342
if (len == ptr->query_len)
2343
snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial,
2344
ptr->retry, ptr->query);
2345
break;
2346
}
2347
spin_unlock(&tomoyo_query_list_lock);
2348
if (buf[0]) {
2349
head->read_buf = buf;
2350
head->r.w[head->r.w_pos++] = buf;
2351
head->r.query_index++;
2352
} else {
2353
kfree(buf);
2354
}
2355
}
2356
2357
/**
2358
* tomoyo_write_answer - Write the supervisor's decision.
2359
*
2360
* @head: Pointer to "struct tomoyo_io_buffer".
2361
*
2362
* Returns 0 on success, -EINVAL otherwise.
2363
*/
2364
static int tomoyo_write_answer(struct tomoyo_io_buffer *head)
2365
{
2366
char *data = head->write_buf;
2367
struct list_head *tmp;
2368
unsigned int serial;
2369
unsigned int answer;
2370
2371
spin_lock(&tomoyo_query_list_lock);
2372
list_for_each(tmp, &tomoyo_query_list) {
2373
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2374
2375
ptr->timer = 0;
2376
}
2377
spin_unlock(&tomoyo_query_list_lock);
2378
if (sscanf(data, "A%u=%u", &serial, &answer) != 2)
2379
return -EINVAL;
2380
spin_lock(&tomoyo_query_list_lock);
2381
list_for_each(tmp, &tomoyo_query_list) {
2382
struct tomoyo_query *ptr = list_entry(tmp, typeof(*ptr), list);
2383
2384
if (ptr->serial != serial)
2385
continue;
2386
ptr->answer = answer;
2387
/* Remove from tomoyo_query_list. */
2388
if (ptr->answer)
2389
list_del_init(&ptr->list);
2390
break;
2391
}
2392
spin_unlock(&tomoyo_query_list_lock);
2393
return 0;
2394
}
2395
2396
/**
2397
* tomoyo_read_version: Get version.
2398
*
2399
* @head: Pointer to "struct tomoyo_io_buffer".
2400
*
2401
* Returns version information.
2402
*/
2403
static void tomoyo_read_version(struct tomoyo_io_buffer *head)
2404
{
2405
if (!head->r.eof) {
2406
tomoyo_io_printf(head, "2.6.0");
2407
head->r.eof = true;
2408
}
2409
}
2410
2411
/* String table for /sys/kernel/security/tomoyo/stat interface. */
2412
static const char * const tomoyo_policy_headers[TOMOYO_MAX_POLICY_STAT] = {
2413
[TOMOYO_STAT_POLICY_UPDATES] = "update:",
2414
[TOMOYO_STAT_POLICY_LEARNING] = "violation in learning mode:",
2415
[TOMOYO_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
2416
[TOMOYO_STAT_POLICY_ENFORCING] = "violation in enforcing mode:",
2417
};
2418
2419
/* String table for /sys/kernel/security/tomoyo/stat interface. */
2420
static const char * const tomoyo_memory_headers[TOMOYO_MAX_MEMORY_STAT] = {
2421
[TOMOYO_MEMORY_POLICY] = "policy:",
2422
[TOMOYO_MEMORY_AUDIT] = "audit log:",
2423
[TOMOYO_MEMORY_QUERY] = "query message:",
2424
};
2425
2426
/* Counter for number of updates. */
2427
static atomic_t tomoyo_stat_updated[TOMOYO_MAX_POLICY_STAT];
2428
/* Timestamp counter for last updated. */
2429
static time64_t tomoyo_stat_modified[TOMOYO_MAX_POLICY_STAT];
2430
2431
/**
2432
* tomoyo_update_stat - Update statistic counters.
2433
*
2434
* @index: Index for policy type.
2435
*
2436
* Returns nothing.
2437
*/
2438
void tomoyo_update_stat(const u8 index)
2439
{
2440
atomic_inc(&tomoyo_stat_updated[index]);
2441
tomoyo_stat_modified[index] = ktime_get_real_seconds();
2442
}
2443
2444
/**
2445
* tomoyo_read_stat - Read statistic data.
2446
*
2447
* @head: Pointer to "struct tomoyo_io_buffer".
2448
*
2449
* Returns nothing.
2450
*/
2451
static void tomoyo_read_stat(struct tomoyo_io_buffer *head)
2452
{
2453
u8 i;
2454
unsigned int total = 0;
2455
2456
if (head->r.eof)
2457
return;
2458
for (i = 0; i < TOMOYO_MAX_POLICY_STAT; i++) {
2459
tomoyo_io_printf(head, "Policy %-30s %10u",
2460
tomoyo_policy_headers[i],
2461
atomic_read(&tomoyo_stat_updated[i]));
2462
if (tomoyo_stat_modified[i]) {
2463
struct tomoyo_time stamp;
2464
2465
tomoyo_convert_time(tomoyo_stat_modified[i], &stamp);
2466
tomoyo_io_printf(head, " (Last: %04u/%02u/%02u %02u:%02u:%02u)",
2467
stamp.year, stamp.month, stamp.day,
2468
stamp.hour, stamp.min, stamp.sec);
2469
}
2470
tomoyo_set_lf(head);
2471
}
2472
for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++) {
2473
unsigned int used = tomoyo_memory_used[i];
2474
2475
total += used;
2476
tomoyo_io_printf(head, "Memory used by %-22s %10u",
2477
tomoyo_memory_headers[i], used);
2478
used = tomoyo_memory_quota[i];
2479
if (used)
2480
tomoyo_io_printf(head, " (Quota: %10u)", used);
2481
tomoyo_set_lf(head);
2482
}
2483
tomoyo_io_printf(head, "Total memory used: %10u\n",
2484
total);
2485
head->r.eof = true;
2486
}
2487
2488
/**
2489
* tomoyo_write_stat - Set memory quota.
2490
*
2491
* @head: Pointer to "struct tomoyo_io_buffer".
2492
*
2493
* Returns 0.
2494
*/
2495
static int tomoyo_write_stat(struct tomoyo_io_buffer *head)
2496
{
2497
char *data = head->write_buf;
2498
u8 i;
2499
2500
if (tomoyo_str_starts(&data, "Memory used by "))
2501
for (i = 0; i < TOMOYO_MAX_MEMORY_STAT; i++)
2502
if (tomoyo_str_starts(&data, tomoyo_memory_headers[i]))
2503
sscanf(data, "%u", &tomoyo_memory_quota[i]);
2504
return 0;
2505
}
2506
2507
/**
2508
* tomoyo_open_control - open() for /sys/kernel/security/tomoyo/ interface.
2509
*
2510
* @type: Type of interface.
2511
* @file: Pointer to "struct file".
2512
*
2513
* Returns 0 on success, negative value otherwise.
2514
*/
2515
int tomoyo_open_control(const u8 type, struct file *file)
2516
{
2517
struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
2518
2519
if (!head)
2520
return -ENOMEM;
2521
mutex_init(&head->io_sem);
2522
head->type = type;
2523
switch (type) {
2524
case TOMOYO_DOMAINPOLICY:
2525
/* /sys/kernel/security/tomoyo/domain_policy */
2526
head->write = tomoyo_write_domain;
2527
head->read = tomoyo_read_domain;
2528
break;
2529
case TOMOYO_EXCEPTIONPOLICY:
2530
/* /sys/kernel/security/tomoyo/exception_policy */
2531
head->write = tomoyo_write_exception;
2532
head->read = tomoyo_read_exception;
2533
break;
2534
case TOMOYO_AUDIT:
2535
/* /sys/kernel/security/tomoyo/audit */
2536
head->poll = tomoyo_poll_log;
2537
head->read = tomoyo_read_log;
2538
break;
2539
case TOMOYO_PROCESS_STATUS:
2540
/* /sys/kernel/security/tomoyo/.process_status */
2541
head->write = tomoyo_write_pid;
2542
head->read = tomoyo_read_pid;
2543
break;
2544
case TOMOYO_VERSION:
2545
/* /sys/kernel/security/tomoyo/version */
2546
head->read = tomoyo_read_version;
2547
head->readbuf_size = 128;
2548
break;
2549
case TOMOYO_STAT:
2550
/* /sys/kernel/security/tomoyo/stat */
2551
head->write = tomoyo_write_stat;
2552
head->read = tomoyo_read_stat;
2553
head->readbuf_size = 1024;
2554
break;
2555
case TOMOYO_PROFILE:
2556
/* /sys/kernel/security/tomoyo/profile */
2557
head->write = tomoyo_write_profile;
2558
head->read = tomoyo_read_profile;
2559
break;
2560
case TOMOYO_QUERY: /* /sys/kernel/security/tomoyo/query */
2561
head->poll = tomoyo_poll_query;
2562
head->write = tomoyo_write_answer;
2563
head->read = tomoyo_read_query;
2564
break;
2565
case TOMOYO_MANAGER:
2566
/* /sys/kernel/security/tomoyo/manager */
2567
head->write = tomoyo_write_manager;
2568
head->read = tomoyo_read_manager;
2569
break;
2570
}
2571
if (!(file->f_mode & FMODE_READ)) {
2572
/*
2573
* No need to allocate read_buf since it is not opened
2574
* for reading.
2575
*/
2576
head->read = NULL;
2577
head->poll = NULL;
2578
} else if (!head->poll) {
2579
/* Don't allocate read_buf for poll() access. */
2580
if (!head->readbuf_size)
2581
head->readbuf_size = 4096 * 2;
2582
head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
2583
if (!head->read_buf) {
2584
kfree(head);
2585
return -ENOMEM;
2586
}
2587
}
2588
if (!(file->f_mode & FMODE_WRITE)) {
2589
/*
2590
* No need to allocate write_buf since it is not opened
2591
* for writing.
2592
*/
2593
head->write = NULL;
2594
} else if (head->write) {
2595
head->writebuf_size = 4096 * 2;
2596
head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
2597
if (!head->write_buf) {
2598
kfree(head->read_buf);
2599
kfree(head);
2600
return -ENOMEM;
2601
}
2602
}
2603
/*
2604
* If the file is /sys/kernel/security/tomoyo/query , increment the
2605
* observer counter.
2606
* The obserber counter is used by tomoyo_supervisor() to see if
2607
* there is some process monitoring /sys/kernel/security/tomoyo/query.
2608
*/
2609
if (type == TOMOYO_QUERY)
2610
atomic_inc(&tomoyo_query_observers);
2611
file->private_data = head;
2612
tomoyo_notify_gc(head, true);
2613
return 0;
2614
}
2615
2616
/**
2617
* tomoyo_poll_control - poll() for /sys/kernel/security/tomoyo/ interface.
2618
*
2619
* @file: Pointer to "struct file".
2620
* @wait: Pointer to "poll_table". Maybe NULL.
2621
*
2622
* Returns EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM if ready to read/write,
2623
* EPOLLOUT | EPOLLWRNORM otherwise.
2624
*/
2625
__poll_t tomoyo_poll_control(struct file *file, poll_table *wait)
2626
{
2627
struct tomoyo_io_buffer *head = file->private_data;
2628
2629
if (head->poll)
2630
return head->poll(file, wait) | EPOLLOUT | EPOLLWRNORM;
2631
return EPOLLIN | EPOLLRDNORM | EPOLLOUT | EPOLLWRNORM;
2632
}
2633
2634
/**
2635
* tomoyo_set_namespace_cursor - Set namespace to read.
2636
*
2637
* @head: Pointer to "struct tomoyo_io_buffer".
2638
*
2639
* Returns nothing.
2640
*/
2641
static inline void tomoyo_set_namespace_cursor(struct tomoyo_io_buffer *head)
2642
{
2643
struct list_head *ns;
2644
2645
if (head->type != TOMOYO_EXCEPTIONPOLICY &&
2646
head->type != TOMOYO_PROFILE)
2647
return;
2648
/*
2649
* If this is the first read, or reading previous namespace finished
2650
* and has more namespaces to read, update the namespace cursor.
2651
*/
2652
ns = head->r.ns;
2653
if (!ns || (head->r.eof && ns->next != &tomoyo_namespace_list)) {
2654
/* Clearing is OK because tomoyo_flush() returned true. */
2655
memset(&head->r, 0, sizeof(head->r));
2656
head->r.ns = ns ? ns->next : tomoyo_namespace_list.next;
2657
}
2658
}
2659
2660
/**
2661
* tomoyo_has_more_namespace - Check for unread namespaces.
2662
*
2663
* @head: Pointer to "struct tomoyo_io_buffer".
2664
*
2665
* Returns true if we have more entries to print, false otherwise.
2666
*/
2667
static inline bool tomoyo_has_more_namespace(struct tomoyo_io_buffer *head)
2668
{
2669
return (head->type == TOMOYO_EXCEPTIONPOLICY ||
2670
head->type == TOMOYO_PROFILE) && head->r.eof &&
2671
head->r.ns->next != &tomoyo_namespace_list;
2672
}
2673
2674
/**
2675
* tomoyo_read_control - read() for /sys/kernel/security/tomoyo/ interface.
2676
*
2677
* @head: Pointer to "struct tomoyo_io_buffer".
2678
* @buffer: Pointer to buffer to write to.
2679
* @buffer_len: Size of @buffer.
2680
*
2681
* Returns bytes read on success, negative value otherwise.
2682
*/
2683
ssize_t tomoyo_read_control(struct tomoyo_io_buffer *head, char __user *buffer,
2684
const int buffer_len)
2685
{
2686
int len;
2687
int idx;
2688
2689
if (!head->read)
2690
return -EINVAL;
2691
if (mutex_lock_interruptible(&head->io_sem))
2692
return -EINTR;
2693
head->read_user_buf = buffer;
2694
head->read_user_buf_avail = buffer_len;
2695
idx = tomoyo_read_lock();
2696
if (tomoyo_flush(head))
2697
/* Call the policy handler. */
2698
do {
2699
tomoyo_set_namespace_cursor(head);
2700
head->read(head);
2701
} while (tomoyo_flush(head) &&
2702
tomoyo_has_more_namespace(head));
2703
tomoyo_read_unlock(idx);
2704
len = head->read_user_buf - buffer;
2705
mutex_unlock(&head->io_sem);
2706
return len;
2707
}
2708
2709
/**
2710
* tomoyo_parse_policy - Parse a policy line.
2711
*
2712
* @head: Pointer to "struct tomoyo_io_buffer".
2713
* @line: Line to parse.
2714
*
2715
* Returns 0 on success, negative value otherwise.
2716
*
2717
* Caller holds tomoyo_read_lock().
2718
*/
2719
static int tomoyo_parse_policy(struct tomoyo_io_buffer *head, char *line)
2720
{
2721
/* Delete request? */
2722
head->w.is_delete = !strncmp(line, "delete ", 7);
2723
if (head->w.is_delete)
2724
memmove(line, line + 7, strlen(line + 7) + 1);
2725
/* Selecting namespace to update. */
2726
if (head->type == TOMOYO_EXCEPTIONPOLICY ||
2727
head->type == TOMOYO_PROFILE) {
2728
if (*line == '<') {
2729
char *cp = strchr(line, ' ');
2730
2731
if (cp) {
2732
*cp++ = '\0';
2733
head->w.ns = tomoyo_assign_namespace(line);
2734
memmove(line, cp, strlen(cp) + 1);
2735
} else
2736
head->w.ns = NULL;
2737
} else
2738
head->w.ns = &tomoyo_kernel_namespace;
2739
/* Don't allow updating if namespace is invalid. */
2740
if (!head->w.ns)
2741
return -ENOENT;
2742
}
2743
/* Do the update. */
2744
return head->write(head);
2745
}
2746
2747
/**
2748
* tomoyo_write_control - write() for /sys/kernel/security/tomoyo/ interface.
2749
*
2750
* @head: Pointer to "struct tomoyo_io_buffer".
2751
* @buffer: Pointer to buffer to read from.
2752
* @buffer_len: Size of @buffer.
2753
*
2754
* Returns @buffer_len on success, negative value otherwise.
2755
*/
2756
ssize_t tomoyo_write_control(struct tomoyo_io_buffer *head,
2757
const char __user *buffer, const int buffer_len)
2758
{
2759
int error = buffer_len;
2760
size_t avail_len = buffer_len;
2761
char *cp0;
2762
int idx;
2763
2764
if (!head->write)
2765
return -EINVAL;
2766
if (mutex_lock_interruptible(&head->io_sem))
2767
return -EINTR;
2768
cp0 = head->write_buf;
2769
head->read_user_buf_avail = 0;
2770
idx = tomoyo_read_lock();
2771
/* Read a line and dispatch it to the policy handler. */
2772
while (avail_len > 0) {
2773
char c;
2774
2775
if (head->w.avail >= head->writebuf_size - 1) {
2776
const int len = head->writebuf_size * 2;
2777
char *cp = kzalloc(len, GFP_NOFS | __GFP_NOWARN);
2778
2779
if (!cp) {
2780
error = -ENOMEM;
2781
break;
2782
}
2783
memmove(cp, cp0, head->w.avail);
2784
kfree(cp0);
2785
head->write_buf = cp;
2786
cp0 = cp;
2787
head->writebuf_size = len;
2788
}
2789
if (get_user(c, buffer)) {
2790
error = -EFAULT;
2791
break;
2792
}
2793
buffer++;
2794
avail_len--;
2795
cp0[head->w.avail++] = c;
2796
if (c != '\n')
2797
continue;
2798
cp0[head->w.avail - 1] = '\0';
2799
head->w.avail = 0;
2800
tomoyo_normalize_line(cp0);
2801
if (!strcmp(cp0, "reset")) {
2802
head->w.ns = &tomoyo_kernel_namespace;
2803
head->w.domain = NULL;
2804
memset(&head->r, 0, sizeof(head->r));
2805
continue;
2806
}
2807
/* Don't allow updating policies by non manager programs. */
2808
switch (head->type) {
2809
case TOMOYO_PROCESS_STATUS:
2810
/* This does not write anything. */
2811
break;
2812
case TOMOYO_DOMAINPOLICY:
2813
if (tomoyo_select_domain(head, cp0))
2814
continue;
2815
fallthrough;
2816
case TOMOYO_EXCEPTIONPOLICY:
2817
if (!strcmp(cp0, "select transition_only")) {
2818
head->r.print_transition_related_only = true;
2819
continue;
2820
}
2821
fallthrough;
2822
default:
2823
if (!tomoyo_manager()) {
2824
error = -EPERM;
2825
goto out;
2826
}
2827
}
2828
switch (tomoyo_parse_policy(head, cp0)) {
2829
case -EPERM:
2830
error = -EPERM;
2831
goto out;
2832
case 0:
2833
switch (head->type) {
2834
case TOMOYO_DOMAINPOLICY:
2835
case TOMOYO_EXCEPTIONPOLICY:
2836
case TOMOYO_STAT:
2837
case TOMOYO_PROFILE:
2838
case TOMOYO_MANAGER:
2839
tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
2840
break;
2841
default:
2842
break;
2843
}
2844
break;
2845
}
2846
}
2847
out:
2848
tomoyo_read_unlock(idx);
2849
mutex_unlock(&head->io_sem);
2850
return error;
2851
}
2852
2853
/**
2854
* tomoyo_close_control - close() for /sys/kernel/security/tomoyo/ interface.
2855
*
2856
* @head: Pointer to "struct tomoyo_io_buffer".
2857
*/
2858
void tomoyo_close_control(struct tomoyo_io_buffer *head)
2859
{
2860
/*
2861
* If the file is /sys/kernel/security/tomoyo/query , decrement the
2862
* observer counter.
2863
*/
2864
if (head->type == TOMOYO_QUERY &&
2865
atomic_dec_and_test(&tomoyo_query_observers))
2866
wake_up_all(&tomoyo_answer_wait);
2867
tomoyo_notify_gc(head, false);
2868
}
2869
2870
/**
2871
* tomoyo_check_profile - Check all profiles currently assigned to domains are defined.
2872
*/
2873
void tomoyo_check_profile(void)
2874
{
2875
struct tomoyo_domain_info *domain;
2876
const int idx = tomoyo_read_lock();
2877
2878
tomoyo_policy_loaded = true;
2879
pr_info("TOMOYO: 2.6.0\n");
2880
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
2881
srcu_read_lock_held(&tomoyo_ss)) {
2882
const u8 profile = domain->profile;
2883
struct tomoyo_policy_namespace *ns = domain->ns;
2884
2885
if (ns->profile_version == 20110903) {
2886
pr_info_once("Converting profile version from %u to %u.\n",
2887
20110903, 20150505);
2888
ns->profile_version = 20150505;
2889
}
2890
if (ns->profile_version != 20150505)
2891
pr_err("Profile version %u is not supported.\n",
2892
ns->profile_version);
2893
else if (!ns->profile_ptr[profile])
2894
pr_err("Profile %u (used by '%s') is not defined.\n",
2895
profile, domain->domainname->name);
2896
else
2897
continue;
2898
pr_err("Userland tools for TOMOYO 2.6 must be installed and policy must be initialized.\n");
2899
pr_err("Please see https://tomoyo.sourceforge.net/2.6/ for more information.\n");
2900
panic("STOP!");
2901
}
2902
tomoyo_read_unlock(idx);
2903
pr_info("Mandatory Access Control activated.\n");
2904
}
2905
2906
/**
2907
* tomoyo_load_builtin_policy - Load built-in policy.
2908
*
2909
* Returns nothing.
2910
*/
2911
void __init tomoyo_load_builtin_policy(void)
2912
{
2913
#ifdef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
2914
static char tomoyo_builtin_profile[] __initdata =
2915
"PROFILE_VERSION=20150505\n"
2916
"0-CONFIG={ mode=learning grant_log=no reject_log=yes }\n";
2917
static char tomoyo_builtin_exception_policy[] __initdata =
2918
"aggregator proc:/self/exe /proc/self/exe\n";
2919
static char tomoyo_builtin_domain_policy[] __initdata = "";
2920
static char tomoyo_builtin_manager[] __initdata = "";
2921
static char tomoyo_builtin_stat[] __initdata = "";
2922
#else
2923
/*
2924
* This include file is manually created and contains built-in policy
2925
* named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
2926
* "tomoyo_builtin_domain_policy", "tomoyo_builtin_manager",
2927
* "tomoyo_builtin_stat" in the form of "static char [] __initdata".
2928
*/
2929
#include "builtin-policy.h"
2930
#endif
2931
u8 i;
2932
const int idx = tomoyo_read_lock();
2933
2934
for (i = 0; i < 5; i++) {
2935
struct tomoyo_io_buffer head = { };
2936
char *start = "";
2937
2938
switch (i) {
2939
case 0:
2940
start = tomoyo_builtin_profile;
2941
head.type = TOMOYO_PROFILE;
2942
head.write = tomoyo_write_profile;
2943
break;
2944
case 1:
2945
start = tomoyo_builtin_exception_policy;
2946
head.type = TOMOYO_EXCEPTIONPOLICY;
2947
head.write = tomoyo_write_exception;
2948
break;
2949
case 2:
2950
start = tomoyo_builtin_domain_policy;
2951
head.type = TOMOYO_DOMAINPOLICY;
2952
head.write = tomoyo_write_domain;
2953
break;
2954
case 3:
2955
start = tomoyo_builtin_manager;
2956
head.type = TOMOYO_MANAGER;
2957
head.write = tomoyo_write_manager;
2958
break;
2959
case 4:
2960
start = tomoyo_builtin_stat;
2961
head.type = TOMOYO_STAT;
2962
head.write = tomoyo_write_stat;
2963
break;
2964
}
2965
while (1) {
2966
char *end = strchr(start, '\n');
2967
2968
if (!end)
2969
break;
2970
*end = '\0';
2971
tomoyo_normalize_line(start);
2972
head.write_buf = start;
2973
tomoyo_parse_policy(&head, start);
2974
start = end + 1;
2975
}
2976
}
2977
tomoyo_read_unlock(idx);
2978
#ifdef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
2979
tomoyo_check_profile();
2980
#endif
2981
}
2982
2983