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