1 /* 2 * security/ccsecurity/policy_io.c 3 * 4 * Copyright (C) 2005-2012 NTT DATA CORPORATION 5 * 6 * Version: 1.8.11 2024/07/15 7 */ 8 9 #include "internal.h" 10 11 /***** SECTION1: Constants definition *****/ 12 13 /* Define this to enable debug mode. */ 14 /* #define DEBUG_CONDITION */ 15 16 #ifdef DEBUG_CONDITION 17 #define dprintk printk 18 #else 19 #define dprintk(...) do { } while (0) 20 #endif 21 22 /* Mapping table from "enum ccs_mac_index" to "enum ccs_mac_category_index". */ 23 static const u8 ccs_index2category[CCS_MAX_MAC_INDEX] = { 24 /* CONFIG::file group */ 25 [CCS_MAC_FILE_EXECUTE] = CCS_MAC_CATEGORY_FILE, 26 [CCS_MAC_FILE_OPEN] = CCS_MAC_CATEGORY_FILE, 27 [CCS_MAC_FILE_CREATE] = CCS_MAC_CATEGORY_FILE, 28 [CCS_MAC_FILE_UNLINK] = CCS_MAC_CATEGORY_FILE, 29 #ifdef CONFIG_CCSECURITY_FILE_GETATTR 30 [CCS_MAC_FILE_GETATTR] = CCS_MAC_CATEGORY_FILE, 31 #endif 32 [CCS_MAC_FILE_MKDIR] = CCS_MAC_CATEGORY_FILE, 33 [CCS_MAC_FILE_RMDIR] = CCS_MAC_CATEGORY_FILE, 34 [CCS_MAC_FILE_MKFIFO] = CCS_MAC_CATEGORY_FILE, 35 [CCS_MAC_FILE_MKSOCK] = CCS_MAC_CATEGORY_FILE, 36 [CCS_MAC_FILE_TRUNCATE] = CCS_MAC_CATEGORY_FILE, 37 [CCS_MAC_FILE_SYMLINK] = CCS_MAC_CATEGORY_FILE, 38 [CCS_MAC_FILE_MKBLOCK] = CCS_MAC_CATEGORY_FILE, 39 [CCS_MAC_FILE_MKCHAR] = CCS_MAC_CATEGORY_FILE, 40 [CCS_MAC_FILE_LINK] = CCS_MAC_CATEGORY_FILE, 41 [CCS_MAC_FILE_RENAME] = CCS_MAC_CATEGORY_FILE, 42 [CCS_MAC_FILE_CHMOD] = CCS_MAC_CATEGORY_FILE, 43 [CCS_MAC_FILE_CHOWN] = CCS_MAC_CATEGORY_FILE, 44 [CCS_MAC_FILE_CHGRP] = CCS_MAC_CATEGORY_FILE, 45 [CCS_MAC_FILE_IOCTL] = CCS_MAC_CATEGORY_FILE, 46 [CCS_MAC_FILE_CHROOT] = CCS_MAC_CATEGORY_FILE, 47 [CCS_MAC_FILE_MOUNT] = CCS_MAC_CATEGORY_FILE, 48 [CCS_MAC_FILE_UMOUNT] = CCS_MAC_CATEGORY_FILE, 49 [CCS_MAC_FILE_PIVOT_ROOT] = CCS_MAC_CATEGORY_FILE, 50 #ifdef CONFIG_CCSECURITY_MISC 51 /* CONFIG::misc group */ 52 [CCS_MAC_ENVIRON] = CCS_MAC_CATEGORY_MISC, 53 #endif 54 #ifdef CONFIG_CCSECURITY_NETWORK 55 /* CONFIG::network group */ 56 [CCS_MAC_NETWORK_INET_STREAM_BIND] = CCS_MAC_CATEGORY_NETWORK, 57 [CCS_MAC_NETWORK_INET_STREAM_LISTEN] = CCS_MAC_CATEGORY_NETWORK, 58 [CCS_MAC_NETWORK_INET_STREAM_CONNECT] = CCS_MAC_CATEGORY_NETWORK, 59 [CCS_MAC_NETWORK_INET_STREAM_ACCEPT] = CCS_MAC_CATEGORY_NETWORK, 60 [CCS_MAC_NETWORK_INET_DGRAM_BIND] = CCS_MAC_CATEGORY_NETWORK, 61 [CCS_MAC_NETWORK_INET_DGRAM_SEND] = CCS_MAC_CATEGORY_NETWORK, 62 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 63 [CCS_MAC_NETWORK_INET_DGRAM_RECV] = CCS_MAC_CATEGORY_NETWORK, 64 #endif 65 [CCS_MAC_NETWORK_INET_RAW_BIND] = CCS_MAC_CATEGORY_NETWORK, 66 [CCS_MAC_NETWORK_INET_RAW_SEND] = CCS_MAC_CATEGORY_NETWORK, 67 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 68 [CCS_MAC_NETWORK_INET_RAW_RECV] = CCS_MAC_CATEGORY_NETWORK, 69 #endif 70 [CCS_MAC_NETWORK_UNIX_STREAM_BIND] = CCS_MAC_CATEGORY_NETWORK, 71 [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN] = CCS_MAC_CATEGORY_NETWORK, 72 [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT] = CCS_MAC_CATEGORY_NETWORK, 73 [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT] = CCS_MAC_CATEGORY_NETWORK, 74 [CCS_MAC_NETWORK_UNIX_DGRAM_BIND] = CCS_MAC_CATEGORY_NETWORK, 75 [CCS_MAC_NETWORK_UNIX_DGRAM_SEND] = CCS_MAC_CATEGORY_NETWORK, 76 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 77 [CCS_MAC_NETWORK_UNIX_DGRAM_RECV] = CCS_MAC_CATEGORY_NETWORK, 78 #endif 79 [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND] = CCS_MAC_CATEGORY_NETWORK, 80 [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = CCS_MAC_CATEGORY_NETWORK, 81 [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = CCS_MAC_CATEGORY_NETWORK, 82 [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT] = CCS_MAC_CATEGORY_NETWORK, 83 #endif 84 #ifdef CONFIG_CCSECURITY_IPC 85 /* CONFIG::ipc group */ 86 [CCS_MAC_SIGNAL] = CCS_MAC_CATEGORY_IPC, 87 #endif 88 #ifdef CONFIG_CCSECURITY_CAPABILITY 89 /* CONFIG::capability group */ 90 [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET] = CCS_MAC_CATEGORY_CAPABILITY, 91 [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = CCS_MAC_CATEGORY_CAPABILITY, 92 [CCS_MAC_CAPABILITY_SYS_REBOOT] = CCS_MAC_CATEGORY_CAPABILITY, 93 [CCS_MAC_CAPABILITY_SYS_VHANGUP] = CCS_MAC_CATEGORY_CAPABILITY, 94 [CCS_MAC_CAPABILITY_SYS_SETTIME] = CCS_MAC_CATEGORY_CAPABILITY, 95 [CCS_MAC_CAPABILITY_SYS_NICE] = CCS_MAC_CATEGORY_CAPABILITY, 96 [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME] = CCS_MAC_CATEGORY_CAPABILITY, 97 [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY, 98 [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD] = CCS_MAC_CATEGORY_CAPABILITY, 99 [CCS_MAC_CAPABILITY_SYS_PTRACE] = CCS_MAC_CATEGORY_CAPABILITY, 100 #endif 101 }; 102 103 /* String table for operation mode. */ 104 static const char * const ccs_mode[CCS_CONFIG_MAX_MODE] = { 105 [CCS_CONFIG_DISABLED] = "disabled", 106 [CCS_CONFIG_LEARNING] = "learning", 107 [CCS_CONFIG_PERMISSIVE] = "permissive", 108 [CCS_CONFIG_ENFORCING] = "enforcing" 109 }; 110 111 /* String table for /proc/ccs/profile interface. */ 112 static const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX 113 + CCS_MAX_MAC_CATEGORY_INDEX] = { 114 /* CONFIG::file group */ 115 [CCS_MAC_FILE_EXECUTE] = "execute", 116 [CCS_MAC_FILE_OPEN] = "open", 117 [CCS_MAC_FILE_CREATE] = "create", 118 [CCS_MAC_FILE_UNLINK] = "unlink", 119 #ifdef CONFIG_CCSECURITY_FILE_GETATTR 120 [CCS_MAC_FILE_GETATTR] = "getattr", 121 #endif 122 [CCS_MAC_FILE_MKDIR] = "mkdir", 123 [CCS_MAC_FILE_RMDIR] = "rmdir", 124 [CCS_MAC_FILE_MKFIFO] = "mkfifo", 125 [CCS_MAC_FILE_MKSOCK] = "mksock", 126 [CCS_MAC_FILE_TRUNCATE] = "truncate", 127 [CCS_MAC_FILE_SYMLINK] = "symlink", 128 [CCS_MAC_FILE_MKBLOCK] = "mkblock", 129 [CCS_MAC_FILE_MKCHAR] = "mkchar", 130 [CCS_MAC_FILE_LINK] = "link", 131 [CCS_MAC_FILE_RENAME] = "rename", 132 [CCS_MAC_FILE_CHMOD] = "chmod", 133 [CCS_MAC_FILE_CHOWN] = "chown", 134 [CCS_MAC_FILE_CHGRP] = "chgrp", 135 [CCS_MAC_FILE_IOCTL] = "ioctl", 136 [CCS_MAC_FILE_CHROOT] = "chroot", 137 [CCS_MAC_FILE_MOUNT] = "mount", 138 [CCS_MAC_FILE_UMOUNT] = "unmount", 139 [CCS_MAC_FILE_PIVOT_ROOT] = "pivot_root", 140 #ifdef CONFIG_CCSECURITY_MISC 141 /* CONFIG::misc group */ 142 [CCS_MAC_ENVIRON] = "env", 143 #endif 144 #ifdef CONFIG_CCSECURITY_NETWORK 145 /* CONFIG::network group */ 146 [CCS_MAC_NETWORK_INET_STREAM_BIND] = "inet_stream_bind", 147 [CCS_MAC_NETWORK_INET_STREAM_LISTEN] = "inet_stream_listen", 148 [CCS_MAC_NETWORK_INET_STREAM_CONNECT] = "inet_stream_connect", 149 [CCS_MAC_NETWORK_INET_STREAM_ACCEPT] = "inet_stream_accept", 150 [CCS_MAC_NETWORK_INET_DGRAM_BIND] = "inet_dgram_bind", 151 [CCS_MAC_NETWORK_INET_DGRAM_SEND] = "inet_dgram_send", 152 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 153 [CCS_MAC_NETWORK_INET_DGRAM_RECV] = "inet_dgram_recv", 154 #endif 155 [CCS_MAC_NETWORK_INET_RAW_BIND] = "inet_raw_bind", 156 [CCS_MAC_NETWORK_INET_RAW_SEND] = "inet_raw_send", 157 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 158 [CCS_MAC_NETWORK_INET_RAW_RECV] = "inet_raw_recv", 159 #endif 160 [CCS_MAC_NETWORK_UNIX_STREAM_BIND] = "unix_stream_bind", 161 [CCS_MAC_NETWORK_UNIX_STREAM_LISTEN] = "unix_stream_listen", 162 [CCS_MAC_NETWORK_UNIX_STREAM_CONNECT] = "unix_stream_connect", 163 [CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT] = "unix_stream_accept", 164 [CCS_MAC_NETWORK_UNIX_DGRAM_BIND] = "unix_dgram_bind", 165 [CCS_MAC_NETWORK_UNIX_DGRAM_SEND] = "unix_dgram_send", 166 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 167 [CCS_MAC_NETWORK_UNIX_DGRAM_RECV] = "unix_dgram_recv", 168 #endif 169 [CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND] = "unix_seqpacket_bind", 170 [CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] = "unix_seqpacket_listen", 171 [CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect", 172 [CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT] = "unix_seqpacket_accept", 173 #endif 174 #ifdef CONFIG_CCSECURITY_IPC 175 /* CONFIG::ipc group */ 176 [CCS_MAC_SIGNAL] = "signal", 177 #endif 178 #ifdef CONFIG_CCSECURITY_CAPABILITY 179 /* CONFIG::capability group */ 180 [CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET] = "use_route", 181 [CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = "use_packet", 182 [CCS_MAC_CAPABILITY_SYS_REBOOT] = "SYS_REBOOT", 183 [CCS_MAC_CAPABILITY_SYS_VHANGUP] = "SYS_VHANGUP", 184 [CCS_MAC_CAPABILITY_SYS_SETTIME] = "SYS_TIME", 185 [CCS_MAC_CAPABILITY_SYS_NICE] = "SYS_NICE", 186 [CCS_MAC_CAPABILITY_SYS_SETHOSTNAME] = "SYS_SETHOSTNAME", 187 [CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module", 188 [CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD] = "SYS_KEXEC_LOAD", 189 [CCS_MAC_CAPABILITY_SYS_PTRACE] = "SYS_PTRACE", 190 #endif 191 /* CONFIG group */ 192 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE] = "file", 193 #ifdef CONFIG_CCSECURITY_NETWORK 194 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NETWORK] = "network", 195 #endif 196 #ifdef CONFIG_CCSECURITY_MISC 197 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_MISC] = "misc", 198 #endif 199 #ifdef CONFIG_CCSECURITY_IPC 200 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_IPC] = "ipc", 201 #endif 202 #ifdef CONFIG_CCSECURITY_CAPABILITY 203 [CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_CAPABILITY] = "capability", 204 #endif 205 }; 206 207 /* String table for path operation. */ 208 static const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = { 209 [CCS_TYPE_EXECUTE] = "execute", 210 [CCS_TYPE_READ] = "read", 211 [CCS_TYPE_WRITE] = "write", 212 [CCS_TYPE_APPEND] = "append", 213 [CCS_TYPE_UNLINK] = "unlink", 214 #ifdef CONFIG_CCSECURITY_FILE_GETATTR 215 [CCS_TYPE_GETATTR] = "getattr", 216 #endif 217 [CCS_TYPE_RMDIR] = "rmdir", 218 [CCS_TYPE_TRUNCATE] = "truncate", 219 [CCS_TYPE_SYMLINK] = "symlink", 220 [CCS_TYPE_CHROOT] = "chroot", 221 [CCS_TYPE_UMOUNT] = "unmount", 222 }; 223 224 #ifdef CONFIG_CCSECURITY_NETWORK 225 226 /* String table for socket's operation. */ 227 static const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION] = { 228 [CCS_NETWORK_BIND] = "bind", 229 [CCS_NETWORK_LISTEN] = "listen", 230 [CCS_NETWORK_CONNECT] = "connect", 231 [CCS_NETWORK_ACCEPT] = "accept", 232 [CCS_NETWORK_SEND] = "send", 233 #ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG 234 [CCS_NETWORK_RECV] = "recv", 235 #endif 236 }; 237 238 /* String table for socket's protocols. */ 239 static const char * const ccs_proto_keyword[CCS_SOCK_MAX] = { 240 [SOCK_STREAM] = "stream", 241 [SOCK_DGRAM] = "dgram", 242 [SOCK_RAW] = "raw", 243 [SOCK_SEQPACKET] = "seqpacket", 244 [0] = " ", /* Dummy for avoiding NULL pointer dereference. */ 245 [4] = " ", /* Dummy for avoiding NULL pointer dereference. */ 246 }; 247 248 #endif 249 250 /* String table for categories. */ 251 static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = { 252 [CCS_MAC_CATEGORY_FILE] = "file", 253 #ifdef CONFIG_CCSECURITY_NETWORK 254 [CCS_MAC_CATEGORY_NETWORK] = "network", 255 #endif 256 #ifdef CONFIG_CCSECURITY_MISC 257 [CCS_MAC_CATEGORY_MISC] = "misc", 258 #endif 259 #ifdef CONFIG_CCSECURITY_IPC 260 [CCS_MAC_CATEGORY_IPC] = "ipc", 261 #endif 262 #ifdef CONFIG_CCSECURITY_CAPABILITY 263 [CCS_MAC_CATEGORY_CAPABILITY] = "capability", 264 #endif 265 }; 266 267 /* String table for conditions. */ 268 static const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD] = { 269 [CCS_TASK_UID] = "task.uid", 270 [CCS_TASK_EUID] = "task.euid", 271 [CCS_TASK_SUID] = "task.suid", 272 [CCS_TASK_FSUID] = "task.fsuid", 273 [CCS_TASK_GID] = "task.gid", 274 [CCS_TASK_EGID] = "task.egid", 275 [CCS_TASK_SGID] = "task.sgid", 276 [CCS_TASK_FSGID] = "task.fsgid", 277 [CCS_TASK_PID] = "task.pid", 278 [CCS_TASK_PPID] = "task.ppid", 279 [CCS_EXEC_ARGC] = "exec.argc", 280 [CCS_EXEC_ENVC] = "exec.envc", 281 [CCS_TYPE_IS_SOCKET] = "socket", 282 [CCS_TYPE_IS_SYMLINK] = "symlink", 283 [CCS_TYPE_IS_FILE] = "file", 284 [CCS_TYPE_IS_BLOCK_DEV] = "block", 285 [CCS_TYPE_IS_DIRECTORY] = "directory", 286 [CCS_TYPE_IS_CHAR_DEV] = "char", 287 [CCS_TYPE_IS_FIFO] = "fifo", 288 [CCS_MODE_SETUID] = "setuid", 289 [CCS_MODE_SETGID] = "setgid", 290 [CCS_MODE_STICKY] = "sticky", 291 [CCS_MODE_OWNER_READ] = "owner_read", 292 [CCS_MODE_OWNER_WRITE] = "owner_write", 293 [CCS_MODE_OWNER_EXECUTE] = "owner_execute", 294 [CCS_MODE_GROUP_READ] = "group_read", 295 [CCS_MODE_GROUP_WRITE] = "group_write", 296 [CCS_MODE_GROUP_EXECUTE] = "group_execute", 297 [CCS_MODE_OTHERS_READ] = "others_read", 298 [CCS_MODE_OTHERS_WRITE] = "others_write", 299 [CCS_MODE_OTHERS_EXECUTE] = "others_execute", 300 [CCS_TASK_TYPE] = "task.type", 301 [CCS_TASK_EXECUTE_HANDLER] = "execute_handler", 302 [CCS_EXEC_REALPATH] = "exec.realpath", 303 [CCS_SYMLINK_TARGET] = "symlink.target", 304 [CCS_PATH1_UID] = "path1.uid", 305 [CCS_PATH1_GID] = "path1.gid", 306 [CCS_PATH1_INO] = "path1.ino", 307 [CCS_PATH1_MAJOR] = "path1.major", 308 [CCS_PATH1_MINOR] = "path1.minor", 309 [CCS_PATH1_PERM] = "path1.perm", 310 [CCS_PATH1_TYPE] = "path1.type", 311 [CCS_PATH1_DEV_MAJOR] = "path1.dev_major", 312 [CCS_PATH1_DEV_MINOR] = "path1.dev_minor", 313 [CCS_PATH2_UID] = "path2.uid", 314 [CCS_PATH2_GID] = "path2.gid", 315 [CCS_PATH2_INO] = "path2.ino", 316 [CCS_PATH2_MAJOR] = "path2.major", 317 [CCS_PATH2_MINOR] = "path2.minor", 318 [CCS_PATH2_PERM] = "path2.perm", 319 [CCS_PATH2_TYPE] = "path2.type", 320 [CCS_PATH2_DEV_MAJOR] = "path2.dev_major", 321 [CCS_PATH2_DEV_MINOR] = "path2.dev_minor", 322 [CCS_PATH1_PARENT_UID] = "path1.parent.uid", 323 [CCS_PATH1_PARENT_GID] = "path1.parent.gid", 324 [CCS_PATH1_PARENT_INO] = "path1.parent.ino", 325 [CCS_PATH1_PARENT_PERM] = "path1.parent.perm", 326 [CCS_PATH2_PARENT_UID] = "path2.parent.uid", 327 [CCS_PATH2_PARENT_GID] = "path2.parent.gid", 328 [CCS_PATH2_PARENT_INO] = "path2.parent.ino", 329 [CCS_PATH2_PARENT_PERM] = "path2.parent.perm", 330 }; 331 332 /* String table for PREFERENCE keyword. */ 333 static const char * const ccs_pref_keywords[CCS_MAX_PREF] = { 334 [CCS_PREF_MAX_AUDIT_LOG] = "max_audit_log", 335 [CCS_PREF_MAX_LEARNING_ENTRY] = "max_learning_entry", 336 [CCS_PREF_ENFORCING_PENALTY] = "enforcing_penalty", 337 }; 338 339 /* String table for domain flags. */ 340 const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = { 341 [CCS_DIF_QUOTA_WARNED] = "quota_exceeded\n", 342 [CCS_DIF_TRANSITION_FAILED] = "transition_failed\n", 343 }; 344 345 /* String table for domain transition control keywords. */ 346 static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = { 347 [CCS_TRANSITION_CONTROL_NO_RESET] = "no_reset_domain ", 348 [CCS_TRANSITION_CONTROL_RESET] = "reset_domain ", 349 [CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ", 350 [CCS_TRANSITION_CONTROL_INITIALIZE] = "initialize_domain ", 351 [CCS_TRANSITION_CONTROL_NO_KEEP] = "no_keep_domain ", 352 [CCS_TRANSITION_CONTROL_KEEP] = "keep_domain ", 353 }; 354 355 /* String table for grouping keywords. */ 356 static const char * const ccs_group_name[CCS_MAX_GROUP] = { 357 [CCS_PATH_GROUP] = "path_group ", 358 [CCS_NUMBER_GROUP] = "number_group ", 359 #ifdef CONFIG_CCSECURITY_NETWORK 360 [CCS_ADDRESS_GROUP] = "address_group ", 361 #endif 362 }; 363 364 /* String table for /proc/ccs/stat interface. */ 365 static const char * const ccs_policy_headers[CCS_MAX_POLICY_STAT] = { 366 [CCS_STAT_POLICY_UPDATES] = "update:", 367 [CCS_STAT_POLICY_LEARNING] = "violation in learning mode:", 368 [CCS_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:", 369 [CCS_STAT_POLICY_ENFORCING] = "violation in enforcing mode:", 370 }; 371 372 /* String table for /proc/ccs/stat interface. */ 373 static const char * const ccs_memory_headers[CCS_MAX_MEMORY_STAT] = { 374 [CCS_MEMORY_POLICY] = "policy:", 375 [CCS_MEMORY_AUDIT] = "audit log:", 376 [CCS_MEMORY_QUERY] = "query message:", 377 }; 378 379 /***** SECTION2: Structure definition *****/ 380 381 struct iattr; 382 383 /* Structure for query. */ 384 struct ccs_query { 385 struct list_head list; 386 struct ccs_domain_info *domain; 387 char *query; 388 size_t query_len; 389 unsigned int serial; 390 u8 timer; 391 u8 answer; 392 u8 retry; 393 }; 394 395 /* Structure for audit log. */ 396 struct ccs_log { 397 struct list_head list; 398 char *log; 399 int size; 400 }; 401 402 /***** SECTION3: Prototype definition section *****/ 403 404 int ccs_audit_log(struct ccs_request_info *r); 405 struct ccs_domain_info *ccs_assign_domain(const char *domainname, 406 const bool transit); 407 u8 ccs_get_config(const u8 profile, const u8 index); 408 void ccs_transition_failed(const char *domainname); 409 void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...); 410 411 static bool ccs_correct_domain(const char *domainname); 412 static bool ccs_correct_path(const char *filename); 413 static bool ccs_correct_word(const char *string); 414 static bool ccs_correct_word2(const char *string, size_t len); 415 static bool ccs_domain_def(const unsigned char *buffer); 416 static bool ccs_domain_quota_ok(struct ccs_request_info *r); 417 static bool ccs_flush(struct ccs_io_buffer *head); 418 static bool ccs_get_audit(const struct ccs_request_info *r); 419 static bool ccs_has_more_namespace(struct ccs_io_buffer *head); 420 static bool ccs_manager(void); 421 static bool ccs_namespace_jump(const char *domainname); 422 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv); 423 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp); 424 static bool ccs_parse_name_union(struct ccs_acl_param *param, 425 struct ccs_name_union *ptr); 426 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param, 427 struct ccs_name_union *ptr); 428 static bool ccs_parse_number_union(struct ccs_acl_param *param, 429 struct ccs_number_union *ptr); 430 static bool ccs_permstr(const char *string, const char *keyword); 431 static bool ccs_print_condition(struct ccs_io_buffer *head, 432 const struct ccs_condition *cond); 433 static bool ccs_print_entry(struct ccs_io_buffer *head, 434 const struct ccs_acl_info *acl); 435 static bool ccs_print_group(struct ccs_io_buffer *head, 436 const struct ccs_group *group); 437 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list); 438 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx); 439 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx); 440 static bool ccs_same_condition(const struct ccs_condition *a, 441 const struct ccs_condition *b); 442 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data); 443 static bool ccs_set_lf(struct ccs_io_buffer *head); 444 static bool ccs_str_starts(char **src, const char *find); 445 static char *ccs_get_transit_preference(struct ccs_acl_param *param, 446 struct ccs_condition *e); 447 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt, 448 va_list args); 449 static char *ccs_print_bprm(struct linux_binprm *bprm, 450 struct ccs_page_dump *dump); 451 static char *ccs_print_header(struct ccs_request_info *r); 452 static char *ccs_read_token(struct ccs_acl_param *param); 453 static const char *ccs_yesno(const unsigned int value); 454 static const struct ccs_path_info *ccs_get_domainname 455 (struct ccs_acl_param *param); 456 static const struct ccs_path_info *ccs_get_dqword(char *start); 457 static int __init ccs_init_module(void); 458 static int ccs_delete_domain(char *domainname); 459 static int ccs_open(struct inode *inode, struct file *file); 460 static int ccs_parse_policy(struct ccs_io_buffer *head, char *line); 461 static int ccs_release(struct inode *inode, struct file *file); 462 static int ccs_set_mode(char *name, const char *value, 463 struct ccs_profile *profile); 464 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...) 465 __printf(2, 3); 466 static int ccs_truncate(char *str); 467 static int ccs_update_acl(const int size, struct ccs_acl_param *param); 468 static int ccs_update_manager_entry(const char *manager, const bool is_delete); 469 static int ccs_update_policy(const int size, struct ccs_acl_param *param); 470 static int ccs_write_acl(struct ccs_policy_namespace *ns, 471 struct list_head *list, char *data, 472 const bool is_delete); 473 static int ccs_write_aggregator(struct ccs_acl_param *param); 474 static int ccs_write_answer(struct ccs_io_buffer *head); 475 static int ccs_write_domain(struct ccs_io_buffer *head); 476 static int ccs_write_exception(struct ccs_io_buffer *head); 477 static int ccs_write_file(struct ccs_acl_param *param); 478 static int ccs_write_group(struct ccs_acl_param *param, const u8 type); 479 static int ccs_write_manager(struct ccs_io_buffer *head); 480 static int ccs_write_pid(struct ccs_io_buffer *head); 481 static int ccs_write_profile(struct ccs_io_buffer *head); 482 static int ccs_write_stat(struct ccs_io_buffer *head); 483 static int ccs_write_task(struct ccs_acl_param *param); 484 static int ccs_write_transition_control(struct ccs_acl_param *param, 485 const u8 type); 486 static s8 ccs_find_yesno(const char *string, const char *find); 487 static ssize_t ccs_read(struct file *file, char __user *buf, size_t count, 488 loff_t *ppos); 489 static ssize_t ccs_read_self(struct file *file, char __user *buf, size_t count, 490 loff_t *ppos); 491 static ssize_t ccs_write(struct file *file, const char __user *buf, 492 size_t count, loff_t *ppos); 493 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry); 494 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param, 495 const bool pref); 496 static struct ccs_domain_info *ccs_find_domain(const char *domainname); 497 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial); 498 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param, 499 const u8 idx); 500 static struct ccs_policy_namespace *ccs_assign_namespace 501 (const char *domainname); 502 static struct ccs_policy_namespace *ccs_find_namespace(const char *name, 503 const unsigned int len); 504 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns, 505 const unsigned int profile); 506 static struct ccs_profile *ccs_profile(const u8 profile); 507 static u8 ccs_condition_type(const char *word); 508 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3); 509 static u8 ccs_parse_ulong(unsigned long *result, char **str); 510 static unsigned int ccs_poll(struct file *file, poll_table *wait); 511 static void __init ccs_create_entry(const char *name, const umode_t mode, 512 struct proc_dir_entry *parent, 513 const u8 key); 514 static void __init ccs_load_builtin_policy(void); 515 static void __init ccs_policy_io_init(void); 516 static void __init ccs_proc_init(void); 517 static void ccs_add_entry(char *header); 518 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...) 519 __printf(3, 4); 520 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...); 521 static void ccs_check_profile(void); 522 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) 523 static void ccs_convert_time(time_t time, struct ccs_time *stamp); 524 #else 525 static void ccs_convert_time(time64_t time, struct ccs_time *stamp); 526 #endif 527 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns); 528 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...) 529 __printf(2, 3); 530 static void ccs_normalize_line(unsigned char *buffer); 531 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config); 532 static void ccs_print_name_union(struct ccs_io_buffer *head, 533 const struct ccs_name_union *ptr); 534 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head, 535 const struct ccs_name_union *ptr); 536 static void ccs_print_namespace(struct ccs_io_buffer *head); 537 static void ccs_print_number_union(struct ccs_io_buffer *head, 538 const struct ccs_number_union *ptr); 539 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head, 540 const struct ccs_number_union *ptr); 541 static void ccs_read_domain(struct ccs_io_buffer *head); 542 static void ccs_read_exception(struct ccs_io_buffer *head); 543 static void ccs_read_log(struct ccs_io_buffer *head); 544 static void ccs_read_manager(struct ccs_io_buffer *head); 545 static void ccs_read_pid(struct ccs_io_buffer *head); 546 static void ccs_read_profile(struct ccs_io_buffer *head); 547 static void ccs_read_query(struct ccs_io_buffer *head); 548 static void ccs_read_stat(struct ccs_io_buffer *head); 549 static void ccs_read_version(struct ccs_io_buffer *head); 550 static void ccs_set_group(struct ccs_io_buffer *head, const char *category); 551 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head); 552 static void ccs_set_slash(struct ccs_io_buffer *head); 553 static void ccs_set_space(struct ccs_io_buffer *head); 554 static void ccs_set_string(struct ccs_io_buffer *head, const char *string); 555 static void ccs_set_uint(unsigned int *i, const char *string, 556 const char *find); 557 static void ccs_update_stat(const u8 index); 558 static void ccs_update_task_domain(struct ccs_request_info *r); 559 static void ccs_write_log2(struct ccs_request_info *r, int len, 560 const char *fmt, va_list args); 561 562 #ifdef CONFIG_CCSECURITY_PORTRESERVE 563 static bool __ccs_lport_reserved(const u16 port); 564 static int ccs_write_reserved_port(struct ccs_acl_param *param); 565 #endif 566 567 #ifdef CONFIG_CCSECURITY_NETWORK 568 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param, 569 struct ccs_ipaddr_union *ptr); 570 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len, 571 const u32 *ip); 572 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len, 573 const struct in6_addr *ip); 574 static int ccs_write_inet_network(struct ccs_acl_param *param); 575 static int ccs_write_unix_network(struct ccs_acl_param *param); 576 static void ccs_print_ip(char *buf, const unsigned int size, 577 const struct ccs_ipaddr_union *ptr); 578 #endif 579 580 #ifdef CONFIG_CCSECURITY_CAPABILITY 581 static int ccs_write_capability(struct ccs_acl_param *param); 582 #endif 583 584 #ifdef CONFIG_CCSECURITY_MISC 585 static int ccs_write_misc(struct ccs_acl_param *param); 586 #endif 587 588 #ifdef CONFIG_CCSECURITY_IPC 589 static int ccs_write_ipc(struct ccs_acl_param *param); 590 #endif 591 592 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 593 static ssize_t ccs_write_self(struct file *file, const char __user *buf, 594 size_t count, loff_t *ppos); 595 #endif 596 597 /***** SECTION4: Standalone functions section *****/ 598 599 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) 600 601 /** 602 * fatal_signal_pending - Check whether SIGKILL is pending or not. 603 * 604 * @p: Pointer to "struct task_struct". 605 * 606 * Returns true if SIGKILL is pending on @p, false otherwise. 607 * 608 * This is for compatibility with older kernels. 609 */ 610 #define fatal_signal_pending(p) (signal_pending(p) && \ 611 sigismember(&p->pending.signal, SIGKILL)) 612 613 #endif 614 615 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 616 617 /** 618 * __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. 619 * 620 * @wq: The waitqueue to wait on. 621 * @condition: A C expression for the event to wait for. 622 * @ret: Timeout, in jiffies. 623 * 624 * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a 625 * signal, and the remaining jiffies otherwise if the condition evaluated to 626 * true before the timeout elapsed. 627 * 628 * This is for compatibility with older kernels. 629 */ 630 #define __wait_event_interruptible_timeout(wq, condition, ret) \ 631 do { \ 632 wait_queue_t __wait; \ 633 init_waitqueue_entry(&__wait, current); \ 634 \ 635 add_wait_queue(&wq, &__wait); \ 636 for (;;) { \ 637 set_current_state(TASK_INTERRUPTIBLE); \ 638 if (condition) \ 639 break; \ 640 if (!signal_pending(current)) { \ 641 ret = schedule_timeout(ret); \ 642 if (!ret) \ 643 break; \ 644 continue; \ 645 } \ 646 ret = -ERESTARTSYS; \ 647 break; \ 648 } \ 649 current->state = TASK_RUNNING; \ 650 remove_wait_queue(&wq, &__wait); \ 651 } while (0) 652 653 /** 654 * wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. 655 * 656 * @wq: The waitqueue to wait on. 657 * @condition: A C expression for the event to wait for. 658 * @timeout: Timeout, in jiffies. 659 * 660 * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a 661 * signal, and the remaining jiffies otherwise if the condition evaluated to 662 * true before the timeout elapsed. 663 * 664 * This is for compatibility with older kernels. 665 */ 666 #define wait_event_interruptible_timeout(wq, condition, timeout) \ 667 ({ \ 668 long __ret = timeout; \ 669 if (!(condition)) \ 670 __wait_event_interruptible_timeout(wq, condition, __ret); \ 671 __ret; \ 672 }) 673 674 #endif 675 676 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) 677 /** 678 * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss. 679 * 680 * @time: Seconds since 1970/01/01 00:00:00. 681 * @stamp: Pointer to "struct ccs_time". 682 * 683 * Returns nothing. 684 * 685 * This function does not handle Y2038 problem. 686 */ 687 static void ccs_convert_time(time_t time, struct ccs_time *stamp) 688 { 689 static const u16 ccs_eom[2][12] = { 690 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 691 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 692 }; 693 u16 y; 694 u8 m; 695 bool r; 696 stamp->sec = time % 60; 697 time /= 60; 698 stamp->min = time % 60; 699 time /= 60; 700 stamp->hour = time % 24; 701 time /= 24; 702 for (y = 1970; ; y++) { 703 const unsigned short days = (y & 3) ? 365 : 366; 704 if (time < days) 705 break; 706 time -= days; 707 } 708 r = (y & 3) == 0; 709 for (m = 0; m < 11 && time >= ccs_eom[r][m]; m++); 710 if (m) 711 time -= ccs_eom[r][m - 1]; 712 stamp->year = y; 713 stamp->month = ++m; 714 stamp->day = ++time; 715 } 716 #else 717 /** 718 * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss. 719 * 720 * @time: Seconds since 1970/01/01 00:00:00. 721 * @stamp: Pointer to "struct ccs_time". 722 * 723 * Returns nothing. 724 */ 725 static void ccs_convert_time(time64_t time, struct ccs_time *stamp) 726 { 727 struct tm tm; 728 729 time64_to_tm(time, 0, &tm); 730 stamp->sec = tm.tm_sec; 731 stamp->min = tm.tm_min; 732 stamp->hour = tm.tm_hour; 733 stamp->day = tm.tm_mday; 734 stamp->month = tm.tm_mon + 1; 735 stamp->year = tm.tm_year + 1900; 736 } 737 #endif 738 739 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23) 740 #if !defined(RHEL_VERSION) || RHEL_VERSION != 3 741 742 /** 743 * PDE - Get "struct proc_dir_entry". 744 * 745 * @inode: Pointer to "struct inode". 746 * 747 * Returns pointer to "struct proc_dir_entry". 748 * 749 * This is for compatibility with older kernels. 750 */ 751 static inline struct proc_dir_entry *PDE(const struct inode *inode) 752 { 753 return (struct proc_dir_entry *) inode->u.generic_ip; 754 } 755 756 #endif 757 #endif 758 759 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 760 761 /** 762 * proc_notify_change - Update inode's attributes and reflect to the dentry. 763 * 764 * @dentry: Pointer to "struct dentry". 765 * @iattr: Pointer to "struct iattr". 766 * 767 * Returns 0 on success, negative value otherwise. 768 * 769 * The 2.4 kernels don't allow chmod()/chown() for files in /proc, 770 * while the 2.6 kernels allow. 771 * To permit management of /proc/ccs/ interface by non-root user, 772 * I modified to allow chmod()/chown() of /proc/ccs/ interface like 2.6 kernels 773 * by adding "struct inode_operations"->setattr hook. 774 */ 775 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) 776 { 777 struct inode *inode = dentry->d_inode; 778 struct proc_dir_entry *de = PDE(inode); 779 int error; 780 781 error = inode_change_ok(inode, iattr); 782 if (error) 783 goto out; 784 785 error = inode_setattr(inode, iattr); 786 if (error) 787 goto out; 788 789 de->uid = inode->i_uid; 790 de->gid = inode->i_gid; 791 de->mode = inode->i_mode; 792 out: 793 return error; 794 } 795 796 #endif 797 798 #ifdef CONFIG_CCSECURITY_NETWORK 799 800 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && defined(CONFIG_NET) 801 #define ccs_in4_pton in4_pton 802 #define ccs_in6_pton in6_pton 803 #else 804 /* 805 * Routines for parsing IPv4 or IPv6 address. 806 * These are copied from lib/hexdump.c net/core/utils.c . 807 */ 808 #include <linux/ctype.h> 809 810 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 811 static int hex_to_bin(char ch) 812 { 813 if ((ch >= '') && (ch <= '9')) 814 return ch - ''; 815 ch = tolower(ch); 816 if ((ch >= 'a') && (ch <= 'f')) 817 return ch - 'a' + 10; 818 return -1; 819 } 820 #endif 821 822 #define IN6PTON_XDIGIT 0x00010000 823 #define IN6PTON_DIGIT 0x00020000 824 #define IN6PTON_COLON_MASK 0x00700000 825 #define IN6PTON_COLON_1 0x00100000 /* single : requested */ 826 #define IN6PTON_COLON_2 0x00200000 /* second : requested */ 827 #define IN6PTON_COLON_1_2 0x00400000 /* :: requested */ 828 #define IN6PTON_DOT 0x00800000 /* . */ 829 #define IN6PTON_DELIM 0x10000000 830 #define IN6PTON_NULL 0x20000000 /* first/tail */ 831 #define IN6PTON_UNKNOWN 0x40000000 832 833 static inline int xdigit2bin(char c, int delim) 834 { 835 int val; 836 837 if (c == delim || c == '\0') 838 return IN6PTON_DELIM; 839 if (c == ':') 840 return IN6PTON_COLON_MASK; 841 if (c == '.') 842 return IN6PTON_DOT; 843 844 val = hex_to_bin(c); 845 if (val >= 0) 846 return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0); 847 848 if (delim == -1) 849 return IN6PTON_DELIM; 850 return IN6PTON_UNKNOWN; 851 } 852 853 static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim, 854 const char **end) 855 { 856 const char *s; 857 u8 *d; 858 u8 dbuf[4]; 859 int ret = 0; 860 int i; 861 int w = 0; 862 863 if (srclen < 0) 864 srclen = strlen(src); 865 s = src; 866 d = dbuf; 867 i = 0; 868 while (1) { 869 int c; 870 c = xdigit2bin(srclen > 0 ? *s : '\0', delim); 871 if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | 872 IN6PTON_COLON_MASK))) 873 goto out; 874 if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 875 if (w == 0) 876 goto out; 877 *d++ = w & 0xff; 878 w = 0; 879 i++; 880 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 881 if (i != 4) 882 goto out; 883 break; 884 } 885 goto cont; 886 } 887 w = (w * 10) + c; 888 if ((w & 0xffff) > 255) 889 goto out; 890 cont: 891 if (i >= 4) 892 goto out; 893 s++; 894 srclen--; 895 } 896 ret = 1; 897 memcpy(dst, dbuf, sizeof(dbuf)); 898 out: 899 if (end) 900 *end = s; 901 return ret; 902 } 903 904 static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim, 905 const char **end) 906 { 907 const char *s, *tok = NULL; 908 u8 *d, *dc = NULL; 909 u8 dbuf[16]; 910 int ret = 0; 911 int i; 912 int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL; 913 int w = 0; 914 915 memset(dbuf, 0, sizeof(dbuf)); 916 917 s = src; 918 d = dbuf; 919 if (srclen < 0) 920 srclen = strlen(src); 921 922 while (1) { 923 int c; 924 925 c = xdigit2bin(srclen > 0 ? *s : '\0', delim); 926 if (!(c & state)) 927 goto out; 928 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 929 /* process one 16-bit word */ 930 if (!(state & IN6PTON_NULL)) { 931 *d++ = (w >> 8) & 0xff; 932 *d++ = w & 0xff; 933 } 934 w = 0; 935 if (c & IN6PTON_DELIM) { 936 /* We've processed last word */ 937 break; 938 } 939 /* 940 * COLON_1 => XDIGIT 941 * COLON_2 => XDIGIT|DELIM 942 * COLON_1_2 => COLON_2 943 */ 944 switch (state & IN6PTON_COLON_MASK) { 945 case IN6PTON_COLON_2: 946 dc = d; 947 state = IN6PTON_XDIGIT | IN6PTON_DELIM; 948 if (dc - dbuf >= sizeof(dbuf)) 949 state |= IN6PTON_NULL; 950 break; 951 case IN6PTON_COLON_1|IN6PTON_COLON_1_2: 952 state = IN6PTON_XDIGIT | IN6PTON_COLON_2; 953 break; 954 case IN6PTON_COLON_1: 955 state = IN6PTON_XDIGIT; 956 break; 957 case IN6PTON_COLON_1_2: 958 state = IN6PTON_COLON_2; 959 break; 960 default: 961 state = 0; 962 } 963 tok = s + 1; 964 goto cont; 965 } 966 967 if (c & IN6PTON_DOT) { 968 ret = ccs_in4_pton(tok ? tok : s, srclen + 969 (int)(s - tok), d, delim, &s); 970 if (ret > 0) { 971 d += 4; 972 break; 973 } 974 goto out; 975 } 976 977 w = (w << 4) | (0xff & c); 978 state = IN6PTON_COLON_1 | IN6PTON_DELIM; 979 if (!(w & 0xf000)) 980 state |= IN6PTON_XDIGIT; 981 if (!dc && d + 2 < dbuf + sizeof(dbuf)) { 982 state |= IN6PTON_COLON_1_2; 983 state &= ~IN6PTON_DELIM; 984 } 985 if (d + 2 >= dbuf + sizeof(dbuf)) 986 state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2); 987 cont: 988 if ((dc && d + 4 < dbuf + sizeof(dbuf)) || 989 d + 4 == dbuf + sizeof(dbuf)) 990 state |= IN6PTON_DOT; 991 if (d >= dbuf + sizeof(dbuf)) 992 state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK); 993 s++; 994 srclen--; 995 } 996 997 i = 15; d--; 998 999 if (dc) { 1000 while (d >= dc) 1001 dst[i--] = *d--; 1002 while (i >= dc - dbuf) 1003 dst[i--] = 0; 1004 while (i >= 0) 1005 dst[i--] = *d--; 1006 } else 1007 memcpy(dst, dbuf, sizeof(dbuf)); 1008 1009 ret = 1; 1010 out: 1011 if (end) 1012 *end = s; 1013 return ret; 1014 } 1015 #endif 1016 1017 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) 1018 1019 /* 1020 * Routines for printing IPv4 or IPv6 address. 1021 * These are copied from include/linux/kernel.h include/net/ipv6.h 1022 * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified. 1023 */ 1024 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) 1025 #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5 || !defined(RHEL_MINOR) || RHEL_MINOR < 9 1026 static const char hex_asc[] = "0123456789abcdef"; 1027 #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] 1028 #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] 1029 1030 static inline char *pack_hex_byte(char *buf, u8 byte) 1031 { 1032 *buf++ = hex_asc_hi(byte); 1033 *buf++ = hex_asc_lo(byte); 1034 return buf; 1035 } 1036 #endif 1037 #endif 1038 1039 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) 1040 static inline int ipv6_addr_v4mapped(const struct in6_addr *a) 1041 { 1042 return (a->s6_addr32[0] | a->s6_addr32[1] | 1043 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; 1044 } 1045 #endif 1046 1047 static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) 1048 { 1049 return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); 1050 } 1051 1052 static char *ip4_string(char *p, const u8 *addr) 1053 { 1054 /* 1055 * Since this function is called outside vsnprintf(), I can use 1056 * sprintf() here. 1057 */ 1058 return p + 1059 sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]); 1060 } 1061 1062 static char *ip6_compressed_string(char *p, const char *addr) 1063 { 1064 int i, j, range; 1065 unsigned char zerolength[8]; 1066 int longest = 1; 1067 int colonpos = -1; 1068 u16 word; 1069 u8 hi, lo; 1070 bool needcolon = false; 1071 bool useIPv4; 1072 struct in6_addr in6; 1073 1074 memcpy(&in6, addr, sizeof(struct in6_addr)); 1075 1076 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); 1077 1078 memset(zerolength, 0, sizeof(zerolength)); 1079 1080 if (useIPv4) 1081 range = 6; 1082 else 1083 range = 8; 1084 1085 /* find position of longest 0 run */ 1086 for (i = 0; i < range; i++) { 1087 for (j = i; j < range; j++) { 1088 if (in6.s6_addr16[j] != 0) 1089 break; 1090 zerolength[i]++; 1091 } 1092 } 1093 for (i = 0; i < range; i++) { 1094 if (zerolength[i] > longest) { 1095 longest = zerolength[i]; 1096 colonpos = i; 1097 } 1098 } 1099 if (longest == 1) /* don't compress a single 0 */ 1100 colonpos = -1; 1101 1102 /* emit address */ 1103 for (i = 0; i < range; i++) { 1104 if (i == colonpos) { 1105 if (needcolon || i == 0) 1106 *p++ = ':'; 1107 *p++ = ':'; 1108 needcolon = false; 1109 i += longest - 1; 1110 continue; 1111 } 1112 if (needcolon) { 1113 *p++ = ':'; 1114 needcolon = false; 1115 } 1116 /* hex u16 without leading 0s */ 1117 word = ntohs(in6.s6_addr16[i]); 1118 hi = word >> 8; 1119 lo = word & 0xff; 1120 if (hi) { 1121 if (hi > 0x0f) 1122 p = pack_hex_byte(p, hi); 1123 else 1124 *p++ = hex_asc_lo(hi); 1125 p = pack_hex_byte(p, lo); 1126 } else if (lo > 0x0f) 1127 p = pack_hex_byte(p, lo); 1128 else 1129 *p++ = hex_asc_lo(lo); 1130 needcolon = true; 1131 } 1132 1133 if (useIPv4) { 1134 if (needcolon) 1135 *p++ = ':'; 1136 p = ip4_string(p, &in6.s6_addr[12]); 1137 } 1138 *p = '\0'; 1139 1140 return p; 1141 } 1142 #endif 1143 1144 /** 1145 * ccs_print_ipv4 - Print an IPv4 address. 1146 * 1147 * @buffer: Buffer to write to. 1148 * @buffer_len: Size of @buffer. 1149 * @ip: Pointer to "u32 in network byte order". 1150 * 1151 * Returns written length. 1152 */ 1153 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len, 1154 const u32 *ip) 1155 { 1156 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) 1157 return snprintf(buffer, buffer_len, "%pI4", ip); 1158 #else 1159 char addr[sizeof("255.255.255.255")]; 1160 ip4_string(addr, (const u8 *) ip); 1161 return snprintf(buffer, buffer_len, "%s", addr); 1162 #endif 1163 } 1164 1165 /** 1166 * ccs_print_ipv6 - Print an IPv6 address. 1167 * 1168 * @buffer: Buffer to write to. 1169 * @buffer_len: Size of @buffer. 1170 * @ip: Pointer to "struct in6_addr". 1171 * 1172 * Returns written length. 1173 */ 1174 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len, 1175 const struct in6_addr *ip) 1176 { 1177 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) 1178 return snprintf(buffer, buffer_len, "%pI6c", ip); 1179 #else 1180 char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; 1181 ip6_compressed_string(addr, (const u8 *) ip); 1182 return snprintf(buffer, buffer_len, "%s", addr); 1183 #endif 1184 } 1185 1186 /** 1187 * ccs_print_ip - Print an IP address. 1188 * 1189 * @buf: Buffer to write to. 1190 * @size: Size of @buf. 1191 * @ptr: Pointer to "struct ipaddr_union". 1192 * 1193 * Returns nothing. 1194 */ 1195 static void ccs_print_ip(char *buf, const unsigned int size, 1196 const struct ccs_ipaddr_union *ptr) 1197 { 1198 int len; 1199 if (ptr->is_ipv6) 1200 len = ccs_print_ipv6(buf, size, &ptr->ip[0]); 1201 else 1202 len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]); 1203 if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2) 1204 return; 1205 buf[len++] = '-'; 1206 if (ptr->is_ipv6) 1207 ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]); 1208 else 1209 ccs_print_ipv4(buf + len, size - len, 1210 &ptr->ip[1].s6_addr32[0]); 1211 } 1212 1213 #endif 1214 1215 /***** SECTION5: Variables definition section *****/ 1216 1217 /* Permit policy management by non-root user? */ 1218 static bool ccs_manage_by_non_root; 1219 1220 /* Lock for protecting policy. */ 1221 DEFINE_MUTEX(ccs_policy_lock); 1222 1223 /* Has /sbin/init started? */ 1224 bool ccs_policy_loaded; 1225 1226 /* List of namespaces. */ 1227 LIST_HEAD(ccs_namespace_list); 1228 /* True if namespace other than ccs_kernel_namespace is defined. */ 1229 static bool ccs_namespace_enabled; 1230 1231 /* Initial namespace.*/ 1232 static struct ccs_policy_namespace ccs_kernel_namespace; 1233 1234 /* List of "struct ccs_condition". */ 1235 LIST_HEAD(ccs_condition_list); 1236 1237 #ifdef CONFIG_CCSECURITY_PORTRESERVE 1238 /* Bitmap for reserved local port numbers.*/ 1239 static u8 ccs_reserved_port_map[8192]; 1240 #endif 1241 1242 /* Wait queue for kernel -> userspace notification. */ 1243 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait); 1244 /* Wait queue for userspace -> kernel notification. */ 1245 static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait); 1246 1247 /* The list for "struct ccs_query". */ 1248 static LIST_HEAD(ccs_query_list); 1249 1250 /* Lock for manipulating ccs_query_list. */ 1251 static DEFINE_SPINLOCK(ccs_query_list_lock); 1252 1253 /* Number of "struct file" referring /proc/ccs/query interface. */ 1254 static atomic_t ccs_query_observers = ATOMIC_INIT(0); 1255 1256 /* Wait queue for /proc/ccs/audit. */ 1257 static DECLARE_WAIT_QUEUE_HEAD(ccs_log_wait); 1258 1259 /* The list for "struct ccs_log". */ 1260 static LIST_HEAD(ccs_log); 1261 1262 /* Lock for "struct list_head ccs_log". */ 1263 static DEFINE_SPINLOCK(ccs_log_lock); 1264 1265 /* Length of "struct list_head ccs_log". */ 1266 static unsigned int ccs_log_count; 1267 1268 /* Counter for number of updates. */ 1269 static atomic_t ccs_stat_updated[CCS_MAX_POLICY_STAT]; 1270 1271 /* Timestamp counter for last updated. */ 1272 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) 1273 static unsigned int ccs_stat_modified[CCS_MAX_POLICY_STAT]; 1274 #else 1275 static time64_t ccs_stat_modified[CCS_MAX_POLICY_STAT]; 1276 #endif 1277 1278 /* Operations for /proc/ccs/self_domain interface. */ 1279 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 1280 static const struct proc_ops ccs_self_operations = { 1281 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 1282 .proc_write = ccs_write_self, 1283 #endif 1284 .proc_read = ccs_read_self, 1285 .proc_lseek = default_llseek, 1286 }; 1287 #else 1288 static 1289 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) 1290 const 1291 #endif 1292 struct file_operations ccs_self_operations = { 1293 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 1294 .write = ccs_write_self, 1295 #endif 1296 .read = ccs_read_self, 1297 }; 1298 #endif 1299 1300 /* Operations for /proc/ccs/ interface. */ 1301 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 1302 static const struct proc_ops ccs_operations = { 1303 .proc_open = ccs_open, 1304 .proc_release = ccs_release, 1305 .proc_poll = ccs_poll, 1306 .proc_read = ccs_read, 1307 .proc_write = ccs_write, 1308 .proc_lseek = default_llseek, 1309 }; 1310 #else 1311 static 1312 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) 1313 const 1314 #endif 1315 struct file_operations ccs_operations = { 1316 .open = ccs_open, 1317 .release = ccs_release, 1318 .poll = ccs_poll, 1319 .read = ccs_read, 1320 .write = ccs_write, 1321 }; 1322 #endif 1323 1324 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 1325 1326 /* The inode operations for /proc/ccs/ directory. */ 1327 static struct inode_operations ccs_dir_inode_operations; 1328 1329 /* The inode operations for files under /proc/ccs/ directory. */ 1330 static struct inode_operations ccs_file_inode_operations; 1331 1332 #endif 1333 1334 /***** SECTION6: Dependent functions section *****/ 1335 1336 /** 1337 * list_for_each_cookie - iterate over a list with cookie. 1338 * 1339 * @pos: Pointer to "struct list_head". 1340 * @head: Pointer to "struct list_head". 1341 */ 1342 #define list_for_each_cookie(pos, head) \ 1343 for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \ 1344 pos != (head); pos = srcu_dereference(pos->next, &ccs_ss)) 1345 1346 /** 1347 * ccs_read_token - Read a word from a line. 1348 * 1349 * @param: Pointer to "struct ccs_acl_param". 1350 * 1351 * Returns a word on success, "" otherwise. 1352 * 1353 * To allow the caller to skip NULL check, this function returns "" rather than 1354 * NULL if there is no more words to read. 1355 */ 1356 static char *ccs_read_token(struct ccs_acl_param *param) 1357 { 1358 char *pos = param->data; 1359 char *del = strchr(pos, ' '); 1360 if (del) 1361 *del++ = '\0'; 1362 else 1363 del = pos + strlen(pos); 1364 param->data = del; 1365 return pos; 1366 } 1367 1368 /** 1369 * ccs_make_byte - Make byte value from three octal characters. 1370 * 1371 * @c1: The first character. 1372 * @c2: The second character. 1373 * @c3: The third character. 1374 * 1375 * Returns byte value. 1376 */ 1377 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3) 1378 { 1379 return ((c1 - '') << 6) + ((c2 - '') << 3) + (c3 - ''); 1380 } 1381 1382 /** 1383 * ccs_correct_word2 - Check whether the given string follows the naming rules. 1384 * 1385 * @string: The byte sequence to check. Not '\0'-terminated. 1386 * @len: Length of @string. 1387 * 1388 * Returns true if @string follows the naming rules, false otherwise. 1389 */ 1390 static bool ccs_correct_word2(const char *string, size_t len) 1391 { 1392 u8 recursion = 20; 1393 const char *const start = string; 1394 bool in_repetition = false; 1395 if (!len) 1396 goto out; 1397 while (len--) { 1398 unsigned char c = *string++; 1399 if (c == '\\') { 1400 if (!len--) 1401 goto out; 1402 c = *string++; 1403 if (c >= '' && c <= '3') { 1404 unsigned char d; 1405 unsigned char e; 1406 if (!len-- || !len--) 1407 goto out; 1408 d = *string++; 1409 e = *string++; 1410 if (d < '' || d > '7' || e < '' || e > '7') 1411 goto out; 1412 c = ccs_make_byte(c, d, e); 1413 if (c <= ' ' || c >= 127) 1414 continue; 1415 goto out; 1416 } 1417 switch (c) { 1418 case '\\': /* "\\" */ 1419 case '+': /* "\+" */ 1420 case '?': /* "\?" */ 1421 case 'x': /* "\x" */ 1422 case 'a': /* "\a" */ 1423 case '-': /* "\-" */ 1424 continue; 1425 } 1426 if (!recursion--) 1427 goto out; 1428 switch (c) { 1429 case '*': /* "\*" */ 1430 case '@': /* "\@" */ 1431 case '$': /* "\$" */ 1432 case 'X': /* "\X" */ 1433 case 'A': /* "\A" */ 1434 continue; 1435 case '{': /* "/\{" */ 1436 if (string - 3 < start || *(string - 3) != '/') 1437 goto out; 1438 in_repetition = true; 1439 continue; 1440 case '}': /* "\}/" */ 1441 if (*string != '/') 1442 goto out; 1443 if (!in_repetition) 1444 goto out; 1445 in_repetition = false; 1446 continue; 1447 } 1448 goto out; 1449 } else if (in_repetition && c == '/') { 1450 goto out; 1451 } else if (c <= ' ' || c >= 127) { 1452 goto out; 1453 } 1454 } 1455 if (in_repetition) 1456 goto out; 1457 return true; 1458 out: 1459 return false; 1460 } 1461 1462 /** 1463 * ccs_correct_word - Check whether the given string follows the naming rules. 1464 * 1465 * @string: The string to check. 1466 * 1467 * Returns true if @string follows the naming rules, false otherwise. 1468 */ 1469 static bool ccs_correct_word(const char *string) 1470 { 1471 return ccs_correct_word2(string, strlen(string)); 1472 } 1473 1474 /** 1475 * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group". 1476 * 1477 * @param: Pointer to "struct ccs_acl_param". 1478 * @idx: Index number. 1479 * 1480 * Returns pointer to "struct ccs_group" on success, NULL otherwise. 1481 */ 1482 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param, 1483 const u8 idx) 1484 { 1485 struct ccs_group e = { }; 1486 struct ccs_group *group = NULL; 1487 struct list_head *list; 1488 const char *group_name = ccs_read_token(param); 1489 bool found = false; 1490 if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP) 1491 return NULL; 1492 e.group_name = ccs_get_name(group_name); 1493 if (!e.group_name) 1494 return NULL; 1495 if (mutex_lock_interruptible(&ccs_policy_lock)) 1496 goto out; 1497 list = ¶m->ns->group_list[idx]; 1498 list_for_each_entry(group, list, head.list) { 1499 if (e.group_name != group->group_name || 1500 atomic_read(&group->head.users) == CCS_GC_IN_PROGRESS) 1501 continue; 1502 atomic_inc(&group->head.users); 1503 found = true; 1504 break; 1505 } 1506 if (!found) { 1507 struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e)); 1508 if (entry) { 1509 INIT_LIST_HEAD(&entry->member_list); 1510 atomic_set(&entry->head.users, 1); 1511 list_add_tail_rcu(&entry->head.list, list); 1512 group = entry; 1513 found = true; 1514 } 1515 } 1516 mutex_unlock(&ccs_policy_lock); 1517 out: 1518 ccs_put_name(e.group_name); 1519 return found ? group : NULL; 1520 } 1521 1522 /** 1523 * ccs_parse_name_union - Parse a ccs_name_union. 1524 * 1525 * @param: Pointer to "struct ccs_acl_param". 1526 * @ptr: Pointer to "struct ccs_name_union". 1527 * 1528 * Returns true on success, false otherwise. 1529 */ 1530 static bool ccs_parse_name_union(struct ccs_acl_param *param, 1531 struct ccs_name_union *ptr) 1532 { 1533 char *filename; 1534 if (param->data[0] == '@') { 1535 param->data++; 1536 ptr->group = ccs_get_group(param, CCS_PATH_GROUP); 1537 return ptr->group != NULL; 1538 } 1539 filename = ccs_read_token(param); 1540 if (!ccs_correct_word(filename)) 1541 return false; 1542 ptr->filename = ccs_get_name(filename); 1543 return ptr->filename != NULL; 1544 } 1545 1546 /** 1547 * ccs_parse_ulong - Parse an "unsigned long" value. 1548 * 1549 * @result: Pointer to "unsigned long". 1550 * @str: Pointer to string to parse. 1551 * 1552 * Returns one of values in "enum ccs_value_type". 1553 * 1554 * The @src is updated to point the first character after the value 1555 * on success. 1556 */ 1557 static u8 ccs_parse_ulong(unsigned long *result, char **str) 1558 { 1559 const char *cp = *str; 1560 char *ep; 1561 int base = 10; 1562 if (*cp == '') { 1563 char c = *(cp + 1); 1564 if (c == 'x' || c == 'X') { 1565 base = 16; 1566 cp += 2; 1567 } else if (c >= '' && c <= '7') { 1568 base = 8; 1569 cp++; 1570 } 1571 } 1572 *result = simple_strtoul(cp, &ep, base); 1573 if (cp == ep) 1574 return CCS_VALUE_TYPE_INVALID; 1575 *str = ep; 1576 switch (base) { 1577 case 16: 1578 return CCS_VALUE_TYPE_HEXADECIMAL; 1579 case 8: 1580 return CCS_VALUE_TYPE_OCTAL; 1581 default: 1582 return CCS_VALUE_TYPE_DECIMAL; 1583 } 1584 } 1585 1586 /** 1587 * ccs_parse_number_union - Parse a ccs_number_union. 1588 * 1589 * @param: Pointer to "struct ccs_acl_param". 1590 * @ptr: Pointer to "struct ccs_number_union". 1591 * 1592 * Returns true on success, false otherwise. 1593 */ 1594 static bool ccs_parse_number_union(struct ccs_acl_param *param, 1595 struct ccs_number_union *ptr) 1596 { 1597 char *data; 1598 u8 type; 1599 unsigned long v; 1600 memset(ptr, 0, sizeof(*ptr)); 1601 if (param->data[0] == '@') { 1602 param->data++; 1603 ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP); 1604 return ptr->group != NULL; 1605 } 1606 data = ccs_read_token(param); 1607 type = ccs_parse_ulong(&v, &data); 1608 if (type == CCS_VALUE_TYPE_INVALID) 1609 return false; 1610 ptr->values[0] = v; 1611 ptr->value_type[0] = type; 1612 if (!*data) { 1613 ptr->values[1] = v; 1614 ptr->value_type[1] = type; 1615 return true; 1616 } 1617 if (*data++ != '-') 1618 return false; 1619 type = ccs_parse_ulong(&v, &data); 1620 if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v) 1621 return false; 1622 ptr->values[1] = v; 1623 ptr->value_type[1] = type; 1624 return true; 1625 } 1626 1627 #ifdef CONFIG_CCSECURITY_NETWORK 1628 1629 /** 1630 * ccs_parse_ipaddr_union - Parse an IP address. 1631 * 1632 * @param: Pointer to "struct ccs_acl_param". 1633 * @ptr: Pointer to "struct ccs_ipaddr_union". 1634 * 1635 * Returns true on success, false otherwise. 1636 */ 1637 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param, 1638 struct ccs_ipaddr_union *ptr) 1639 { 1640 u8 * const min = ptr->ip[0].in6_u.u6_addr8; 1641 u8 * const max = ptr->ip[1].in6_u.u6_addr8; 1642 char *address = ccs_read_token(param); 1643 const char *end; 1644 if (!strchr(address, ':') && 1645 ccs_in4_pton(address, -1, min, '-', &end) > 0) { 1646 ptr->is_ipv6 = false; 1647 if (!*end) 1648 ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0]; 1649 else if (*end++ != '-' || 1650 ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end) 1651 return false; 1652 return true; 1653 } 1654 if (ccs_in6_pton(address, -1, min, '-', &end) > 0) { 1655 ptr->is_ipv6 = true; 1656 if (!*end) 1657 memmove(max, min, sizeof(u16) * 8); 1658 else if (*end++ != '-' || 1659 ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end) 1660 return false; 1661 return true; 1662 } 1663 return false; 1664 } 1665 1666 #endif 1667 1668 /** 1669 * ccs_get_dqword - ccs_get_name() for a quoted string. 1670 * 1671 * @start: String to save. 1672 * 1673 * Returns pointer to "struct ccs_path_info" on success, NULL otherwise. 1674 */ 1675 static const struct ccs_path_info *ccs_get_dqword(char *start) 1676 { 1677 char *cp = start + strlen(start) - 1; 1678 if (cp == start || *start++ != '"' || *cp != '"') 1679 return NULL; 1680 *cp = '\0'; 1681 if (*start && !ccs_correct_word(start)) 1682 return NULL; 1683 return ccs_get_name(start); 1684 } 1685 1686 /** 1687 * ccs_parse_name_union_quoted - Parse a quoted word. 1688 * 1689 * @param: Pointer to "struct ccs_acl_param". 1690 * @ptr: Pointer to "struct ccs_name_union". 1691 * 1692 * Returns true on success, false otherwise. 1693 */ 1694 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param, 1695 struct ccs_name_union *ptr) 1696 { 1697 char *filename = param->data; 1698 if (*filename == '@') 1699 return ccs_parse_name_union(param, ptr); 1700 ptr->filename = ccs_get_dqword(filename); 1701 return ptr->filename != NULL; 1702 } 1703 1704 /** 1705 * ccs_parse_argv - Parse an argv[] condition part. 1706 * 1707 * @left: Lefthand value. 1708 * @right: Righthand value. 1709 * @argv: Pointer to "struct ccs_argv". 1710 * 1711 * Returns true on success, false otherwise. 1712 */ 1713 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv) 1714 { 1715 if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL || 1716 *left++ != ']' || *left) 1717 return false; 1718 argv->value = ccs_get_dqword(right); 1719 return argv->value != NULL; 1720 } 1721 1722 /** 1723 * ccs_parse_envp - Parse an envp[] condition part. 1724 * 1725 * @left: Lefthand value. 1726 * @right: Righthand value. 1727 * @envp: Pointer to "struct ccs_envp". 1728 * 1729 * Returns true on success, false otherwise. 1730 */ 1731 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp) 1732 { 1733 const struct ccs_path_info *name; 1734 const struct ccs_path_info *value; 1735 char *cp = left + strlen(left) - 1; 1736 if (*cp-- != ']' || *cp != '"') 1737 goto out; 1738 *cp = '\0'; 1739 if (!ccs_correct_word(left)) 1740 goto out; 1741 name = ccs_get_name(left); 1742 if (!name) 1743 goto out; 1744 if (!strcmp(right, "NULL")) { 1745 value = NULL; 1746 } else { 1747 value = ccs_get_dqword(right); 1748 if (!value) { 1749 ccs_put_name(name); 1750 goto out; 1751 } 1752 } 1753 envp->name = name; 1754 envp->value = value; 1755 return true; 1756 out: 1757 return false; 1758 } 1759 1760 /** 1761 * ccs_same_condition - Check for duplicated "struct ccs_condition" entry. 1762 * 1763 * @a: Pointer to "struct ccs_condition". 1764 * @b: Pointer to "struct ccs_condition". 1765 * 1766 * Returns true if @a == @b, false otherwise. 1767 */ 1768 static bool ccs_same_condition(const struct ccs_condition *a, 1769 const struct ccs_condition *b) 1770 { 1771 return a->size == b->size && a->condc == b->condc && 1772 a->numbers_count == b->numbers_count && 1773 a->names_count == b->names_count && 1774 a->argc == b->argc && a->envc == b->envc && 1775 a->grant_log == b->grant_log && 1776 a->exec_transit == b->exec_transit && a->transit == b->transit 1777 && !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 1778 } 1779 1780 /** 1781 * ccs_condition_type - Get condition type. 1782 * 1783 * @word: Keyword string. 1784 * 1785 * Returns one of values in "enum ccs_conditions_index" on success, 1786 * CCS_MAX_CONDITION_KEYWORD otherwise. 1787 */ 1788 static u8 ccs_condition_type(const char *word) 1789 { 1790 u8 i; 1791 for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) { 1792 if (!strcmp(word, ccs_condition_keyword[i])) 1793 break; 1794 } 1795 return i; 1796 } 1797 1798 /** 1799 * ccs_commit_condition - Commit "struct ccs_condition". 1800 * 1801 * @entry: Pointer to "struct ccs_condition". 1802 * 1803 * Returns pointer to "struct ccs_condition" on success, NULL otherwise. 1804 * 1805 * This function merges duplicated entries. This function returns NULL if 1806 * @entry is not duplicated but memory quota for policy has exceeded. 1807 */ 1808 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry) 1809 { 1810 struct ccs_condition *ptr; 1811 bool found = false; 1812 if (mutex_lock_interruptible(&ccs_policy_lock)) { 1813 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__); 1814 ptr = NULL; 1815 found = true; 1816 goto out; 1817 } 1818 list_for_each_entry(ptr, &ccs_condition_list, head.list) { 1819 if (!ccs_same_condition(ptr, entry) || 1820 atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS) 1821 continue; 1822 /* Same entry found. Share this entry. */ 1823 atomic_inc(&ptr->head.users); 1824 found = true; 1825 break; 1826 } 1827 if (!found) { 1828 if (ccs_memory_ok(entry, entry->size)) { 1829 atomic_set(&entry->head.users, 1); 1830 list_add(&entry->head.list, &ccs_condition_list); 1831 } else { 1832 found = true; 1833 ptr = NULL; 1834 } 1835 } 1836 mutex_unlock(&ccs_policy_lock); 1837 out: 1838 if (found) { 1839 ccs_del_condition(&entry->head.list); 1840 kfree(entry); 1841 entry = ptr; 1842 } 1843 return entry; 1844 } 1845 1846 /** 1847 * ccs_correct_path2 - Check whether the given pathname follows the naming rules. 1848 * 1849 * @filename: The pathname to check. 1850 * @len: Length of @filename. 1851 * 1852 * Returns true if @filename follows the naming rules, false otherwise. 1853 */ 1854 static bool ccs_correct_path2(const char *filename, const size_t len) 1855 { 1856 const char *cp1 = memchr(filename, '/', len); 1857 const char *cp2 = memchr(filename, '.', len); 1858 return cp1 && (!cp2 || (cp1 < cp2)) && ccs_correct_word2(filename, len) 1859 && (len < 24 || 1860 memcmp(filename, "auto_domain_transition=\"", 24)); 1861 } 1862 1863 /** 1864 * ccs_correct_path - Check whether the given pathname follows the naming rules. 1865 * 1866 * @filename: The pathname to check. 1867 * 1868 * Returns true if @filename follows the naming rules, false otherwise. 1869 */ 1870 static bool ccs_correct_path(const char *filename) 1871 { 1872 return ccs_correct_path2(filename, strlen(filename)); 1873 } 1874 1875 /** 1876 * ccs_domain_def - Check whether the given token can be a domainname. 1877 * 1878 * @buffer: The token to check. 1879 * 1880 * Returns true if @buffer possibly be a domainname, false otherwise. 1881 */ 1882 static bool ccs_domain_def(const unsigned char *buffer) 1883 { 1884 const unsigned char *cp; 1885 int len; 1886 if (*buffer != '<') 1887 return false; 1888 cp = strchr(buffer, ' '); 1889 if (!cp) 1890 len = strlen(buffer); 1891 else 1892 len = cp - buffer; 1893 if (buffer[len - 1] != '>' || !ccs_correct_word2(buffer + 1, len - 2)) 1894 return false; 1895 return true; 1896 } 1897 1898 /** 1899 * ccs_correct_domain - Check whether the given domainname follows the naming rules. 1900 * 1901 * @domainname: The domainname to check. 1902 * 1903 * Returns true if @domainname follows the naming rules, false otherwise. 1904 */ 1905 static bool ccs_correct_domain(const char *domainname) 1906 { 1907 if (!domainname || !ccs_domain_def(domainname)) 1908 return false; 1909 domainname = strchr(domainname, ' '); 1910 if (!domainname++) 1911 return true; 1912 while (1) { 1913 const char *cp = strchr(domainname, ' '); 1914 const int len = cp ? cp - domainname : strlen(domainname); 1915 if (len == 0) 1916 return true; 1917 if (!ccs_correct_path2(domainname, len)) 1918 return false; 1919 if (!cp) 1920 return true; 1921 domainname += len + 1; 1922 } 1923 } 1924 1925 /** 1926 * ccs_normalize_line - Format string. 1927 * 1928 * @buffer: The line to normalize. 1929 * 1930 * Returns nothing. 1931 * 1932 * Leading and trailing whitespaces are removed. 1933 * Multiple whitespaces are packed into single space. 1934 */ 1935 static void ccs_normalize_line(unsigned char *buffer) 1936 { 1937 unsigned char *sp = buffer; 1938 unsigned char *dp = buffer; 1939 bool first = true; 1940 while (*sp && (*sp <= ' ' || *sp >= 127)) 1941 sp++; 1942 while (*sp) { 1943 if (!first) 1944 *dp++ = ' '; 1945 first = false; 1946 while (*sp > ' ' && *sp < 127) 1947 *dp++ = *sp++; 1948 while (*sp && (*sp <= ' ' || *sp >= 127)) 1949 sp++; 1950 } 1951 *dp = '\0'; 1952 } 1953 1954 /** 1955 * ccs_get_domainname - Read a domainname from a line. 1956 * 1957 * @param: Pointer to "struct ccs_acl_param". 1958 * 1959 * Returns a domainname on success, NULL otherwise. 1960 */ 1961 static const struct ccs_path_info *ccs_get_domainname 1962 (struct ccs_acl_param *param) 1963 { 1964 char *start = param->data; 1965 char *pos = start; 1966 while (*pos) { 1967 char *cp; 1968 size_t len; 1969 if (*pos++ != ' ') 1970 continue; 1971 cp = strchr(pos, ' '); 1972 len = cp ? cp - pos : strlen(pos); 1973 if (ccs_correct_path2(pos, len)) 1974 continue; 1975 *(pos - 1) = '\0'; 1976 break; 1977 } 1978 param->data = pos; 1979 if (ccs_correct_domain(start)) 1980 return ccs_get_name(start); 1981 return NULL; 1982 } 1983 1984 /** 1985 * ccs_get_transit_preference - Parse domain transition preference for execve(). 1986 * 1987 * @param: Pointer to "struct ccs_acl_param". 1988 * @e: Pointer to "struct ccs_condition". 1989 * 1990 * Returns the condition string part. 1991 */ 1992 static char *ccs_get_transit_preference(struct ccs_acl_param *param, 1993 struct ccs_condition *e) 1994 { 1995 char * const pos = param->data; 1996 bool flag; 1997 if (*pos == '<') { 1998 e->transit = ccs_get_domainname(param); 1999 goto done; 2000 } 2001 { 2002 char *cp = strchr(pos, ' '); 2003 if (cp) 2004 *cp = '\0'; 2005 flag = ccs_correct_path(pos) || !strcmp(pos, "keep") || 2006 !strcmp(pos, "initialize") || !strcmp(pos, "reset") || 2007 !strcmp(pos, "child") || !strcmp(pos, "parent"); 2008 if (cp) 2009 *cp = ' '; 2010 } 2011 if (!flag) 2012 return pos; 2013 e->transit = ccs_get_name(ccs_read_token(param)); 2014 done: 2015 if (e->transit) { 2016 e->exec_transit = true; 2017 return param->data; 2018 } 2019 /* 2020 * Return a bad read-only condition string that will let 2021 * ccs_get_condition() return NULL. 2022 */ 2023 return "/"; 2024 } 2025 2026 /** 2027 * ccs_get_condition - Parse condition part. 2028 * 2029 * @param: Pointer to "struct ccs_acl_param". 2030 * @pref: Can include domain transition preference? 2031 * 2032 * Returns pointer to "struct ccs_condition" on success, NULL otherwise. 2033 */ 2034 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param, 2035 const bool pref) 2036 { 2037 struct ccs_condition *entry = NULL; 2038 struct ccs_condition_element *condp = NULL; 2039 struct ccs_number_union *numbers_p = NULL; 2040 struct ccs_name_union *names_p = NULL; 2041 struct ccs_argv *argv = NULL; 2042 struct ccs_envp *envp = NULL; 2043 struct ccs_condition e = { }; 2044 char * const start_of_string = pref ? 2045 ccs_get_transit_preference(param, &e) : param->data; 2046 char * const end_of_string = start_of_string + strlen(start_of_string); 2047 char *pos; 2048 rerun: 2049 pos = start_of_string; 2050 while (1) { 2051 u8 left = -1; 2052 u8 right = -1; 2053 char *left_word = pos; 2054 char *cp; 2055 char *right_word; 2056 bool is_not; 2057 if (!*left_word) 2058 break; 2059 /* 2060 * Since left-hand condition does not allow use of "path_group" 2061 * or "number_group" and environment variable's names do not 2062 * accept '=', it is guaranteed that the original line consists 2063 * of one or more repetition of $left$operator$right blocks 2064 * where "$left is free from '=' and ' '" and "$operator is 2065 * either '=' or '!='" and "$right is free from ' '". 2066 * Therefore, we can reconstruct the original line at the end 2067 * of dry run even if we overwrite $operator with '\0'. 2068 */ 2069 cp = strchr(pos, ' '); 2070 if (cp) { 2071 *cp = '\0'; /* Will restore later. */ 2072 pos = cp + 1; 2073 } else { 2074 pos = ""; 2075 } 2076 right_word = strchr(left_word, '='); 2077 if (!right_word || right_word == left_word) 2078 goto out; 2079 is_not = *(right_word - 1) == '!'; 2080 if (is_not) 2081 *(right_word++ - 1) = '\0'; /* Will restore later. */ 2082 else if (*(right_word + 1) != '=') 2083 *right_word++ = '\0'; /* Will restore later. */ 2084 else 2085 goto out; 2086 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word, 2087 is_not ? "!" : "", right_word); 2088 if (!strcmp(left_word, "grant_log")) { 2089 if (entry) { 2090 if (is_not || 2091 entry->grant_log != CCS_GRANTLOG_AUTO) 2092 goto out; 2093 else if (!strcmp(right_word, "yes")) 2094 entry->grant_log = CCS_GRANTLOG_YES; 2095 else if (!strcmp(right_word, "no")) 2096 entry->grant_log = CCS_GRANTLOG_NO; 2097 else 2098 goto out; 2099 } 2100 continue; 2101 } 2102 if (!strcmp(left_word, "auto_domain_transition")) { 2103 if (entry) { 2104 if (is_not || entry->transit) 2105 goto out; 2106 entry->transit = ccs_get_dqword(right_word); 2107 if (!entry->transit || 2108 (!ccs_correct_path(entry->transit->name) && 2109 !ccs_domain_def(entry->transit->name))) 2110 goto out; 2111 } 2112 continue; 2113 } 2114 if (!strncmp(left_word, "exec.argv[", 10)) { 2115 if (!argv) { 2116 e.argc++; 2117 e.condc++; 2118 } else { 2119 e.argc--; 2120 e.condc--; 2121 left = CCS_ARGV_ENTRY; 2122 argv->is_not = is_not; 2123 if (!ccs_parse_argv(left_word + 10, 2124 right_word, argv++)) 2125 goto out; 2126 } 2127 goto store_value; 2128 } 2129 if (!strncmp(left_word, "exec.envp[\"", 11)) { 2130 if (!envp) { 2131 e.envc++; 2132 e.condc++; 2133 } else { 2134 e.envc--; 2135 e.condc--; 2136 left = CCS_ENVP_ENTRY; 2137 envp->is_not = is_not; 2138 if (!ccs_parse_envp(left_word + 11, 2139 right_word, envp++)) 2140 goto out; 2141 } 2142 goto store_value; 2143 } 2144 left = ccs_condition_type(left_word); 2145 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word, 2146 left); 2147 if (left == CCS_MAX_CONDITION_KEYWORD) { 2148 if (!numbers_p) { 2149 e.numbers_count++; 2150 } else { 2151 e.numbers_count--; 2152 left = CCS_NUMBER_UNION; 2153 param->data = left_word; 2154 if (*left_word == '@' || 2155 !ccs_parse_number_union(param, 2156 numbers_p++)) 2157 goto out; 2158 } 2159 } 2160 if (!condp) 2161 e.condc++; 2162 else 2163 e.condc--; 2164 if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) { 2165 if (!names_p) { 2166 e.names_count++; 2167 } else { 2168 e.names_count--; 2169 right = CCS_NAME_UNION; 2170 param->data = right_word; 2171 if (!ccs_parse_name_union_quoted(param, 2172 names_p++)) 2173 goto out; 2174 } 2175 goto store_value; 2176 } 2177 right = ccs_condition_type(right_word); 2178 if (right == CCS_MAX_CONDITION_KEYWORD) { 2179 if (!numbers_p) { 2180 e.numbers_count++; 2181 } else { 2182 e.numbers_count--; 2183 right = CCS_NUMBER_UNION; 2184 param->data = right_word; 2185 if (!ccs_parse_number_union(param, 2186 numbers_p++)) 2187 goto out; 2188 } 2189 } 2190 store_value: 2191 if (!condp) { 2192 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " 2193 "match=%u\n", __LINE__, left, right, !is_not); 2194 continue; 2195 } 2196 condp->left = left; 2197 condp->right = right; 2198 condp->equals = !is_not; 2199 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n", 2200 __LINE__, condp->left, condp->right, 2201 condp->equals); 2202 condp++; 2203 } 2204 dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n", 2205 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc, 2206 e.envc); 2207 if (entry) { 2208 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc | 2209 e.condc); 2210 return ccs_commit_condition(entry); 2211 } 2212 e.size = sizeof(*entry) 2213 + e.condc * sizeof(struct ccs_condition_element) 2214 + e.numbers_count * sizeof(struct ccs_number_union) 2215 + e.names_count * sizeof(struct ccs_name_union) 2216 + e.argc * sizeof(struct ccs_argv) 2217 + e.envc * sizeof(struct ccs_envp); 2218 entry = kzalloc(e.size, CCS_GFP_FLAGS); 2219 if (!entry) 2220 goto out2; 2221 *entry = e; 2222 e.transit = NULL; 2223 condp = (struct ccs_condition_element *) (entry + 1); 2224 numbers_p = (struct ccs_number_union *) (condp + e.condc); 2225 names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count); 2226 argv = (struct ccs_argv *) (names_p + e.names_count); 2227 envp = (struct ccs_envp *) (argv + e.argc); 2228 { 2229 bool flag = false; 2230 for (pos = start_of_string; pos < end_of_string; pos++) { 2231 if (*pos) 2232 continue; 2233 if (flag) /* Restore " ". */ 2234 *pos = ' '; 2235 else if (*(pos + 1) == '=') /* Restore "!=". */ 2236 *pos = '!'; 2237 else /* Restore "=". */ 2238 *pos = '='; 2239 flag = !flag; 2240 } 2241 } 2242 goto rerun; 2243 out: 2244 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__); 2245 if (entry) { 2246 ccs_del_condition(&entry->head.list); 2247 kfree(entry); 2248 } 2249 out2: 2250 ccs_put_name(e.transit); 2251 return NULL; 2252 } 2253 2254 /** 2255 * ccs_yesno - Return "yes" or "no". 2256 * 2257 * @value: Bool value. 2258 * 2259 * Returns "yes" if @value is not 0, "no" otherwise. 2260 */ 2261 static const char *ccs_yesno(const unsigned int value) 2262 { 2263 return value ? "yes" : "no"; 2264 } 2265 2266 /** 2267 * ccs_addprintf - strncat()-like-snprintf(). 2268 * 2269 * @buffer: Buffer to write to. Must be '\0'-terminated. 2270 * @len: Size of @buffer. 2271 * @fmt: The printf()'s format string, followed by parameters. 2272 * 2273 * Returns nothing. 2274 */ 2275 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...) 2276 { 2277 va_list args; 2278 const int pos = strlen(buffer); 2279 va_start(args, fmt); 2280 vsnprintf(buffer + pos, len - pos - 1, fmt, args); 2281 va_end(args); 2282 } 2283 2284 /** 2285 * ccs_flush - Flush queued string to userspace's buffer. 2286 * 2287 * @head: Pointer to "struct ccs_io_buffer". 2288 * 2289 * Returns true if all data was flushed, false otherwise. 2290 */ 2291 static bool ccs_flush(struct ccs_io_buffer *head) 2292 { 2293 while (head->r.w_pos) { 2294 const char *w = head->r.w[0]; 2295 size_t len = strlen(w); 2296 if (len) { 2297 if (len > head->read_user_buf_avail) 2298 len = head->read_user_buf_avail; 2299 if (!len) 2300 return false; 2301 if (copy_to_user(head->read_user_buf, w, len)) 2302 return false; 2303 head->read_user_buf_avail -= len; 2304 head->read_user_buf += len; 2305 w += len; 2306 } 2307 head->r.w[0] = w; 2308 if (*w) 2309 return false; 2310 /* Add '\0' for audit logs and query. */ 2311 if (head->type == CCS_AUDIT || head->type == CCS_QUERY) { 2312 if (!head->read_user_buf_avail || 2313 copy_to_user(head->read_user_buf, "", 1)) 2314 return false; 2315 head->read_user_buf_avail--; 2316 head->read_user_buf++; 2317 } 2318 head->r.w_pos--; 2319 for (len = 0; len < head->r.w_pos; len++) 2320 head->r.w[len] = head->r.w[len + 1]; 2321 } 2322 head->r.avail = 0; 2323 return true; 2324 } 2325 2326 /** 2327 * ccs_set_string - Queue string to "struct ccs_io_buffer" structure. 2328 * 2329 * @head: Pointer to "struct ccs_io_buffer". 2330 * @string: String to print. 2331 * 2332 * Returns nothing. 2333 * 2334 * Note that @string has to be kept valid until @head is kfree()d. 2335 * This means that char[] allocated on stack memory cannot be passed to 2336 * this function. Use ccs_io_printf() for char[] allocated on stack memory. 2337 */ 2338 static void ccs_set_string(struct ccs_io_buffer *head, const char *string) 2339 { 2340 if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) { 2341 head->r.w[head->r.w_pos++] = string; 2342 ccs_flush(head); 2343 } else 2344 printk(KERN_WARNING "Too many words in a line.\n"); 2345 } 2346 2347 /** 2348 * ccs_io_printf - printf() to "struct ccs_io_buffer" structure. 2349 * 2350 * @head: Pointer to "struct ccs_io_buffer". 2351 * @fmt: The printf()'s format string, followed by parameters. 2352 * 2353 * Returns nothing. 2354 */ 2355 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...) 2356 { 2357 va_list args; 2358 size_t len; 2359 size_t pos = head->r.avail; 2360 int size = head->readbuf_size - pos; 2361 if (size <= 0) 2362 return; 2363 va_start(args, fmt); 2364 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; 2365 va_end(args); 2366 if (pos + len >= head->readbuf_size) { 2367 printk(KERN_WARNING "Too many words in a line.\n"); 2368 return; 2369 } 2370 head->r.avail += len; 2371 ccs_set_string(head, head->read_buf + pos); 2372 } 2373 2374 /** 2375 * ccs_set_space - Put a space to "struct ccs_io_buffer" structure. 2376 * 2377 * @head: Pointer to "struct ccs_io_buffer". 2378 * 2379 * Returns nothing. 2380 */ 2381 static void ccs_set_space(struct ccs_io_buffer *head) 2382 { 2383 ccs_set_string(head, " "); 2384 } 2385 2386 /** 2387 * ccs_set_lf - Put a line feed to "struct ccs_io_buffer" structure. 2388 * 2389 * @head: Pointer to "struct ccs_io_buffer". 2390 * 2391 * Returns true if all data was flushed, false otherwise. 2392 */ 2393 static bool ccs_set_lf(struct ccs_io_buffer *head) 2394 { 2395 ccs_set_string(head, "\n"); 2396 return !head->r.w_pos; 2397 } 2398 2399 /** 2400 * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure. 2401 * 2402 * @head: Pointer to "struct ccs_io_buffer". 2403 * 2404 * Returns nothing. 2405 */ 2406 static void ccs_set_slash(struct ccs_io_buffer *head) 2407 { 2408 ccs_set_string(head, "/"); 2409 } 2410 2411 /** 2412 * ccs_init_policy_namespace - Initialize namespace. 2413 * 2414 * @ns: Pointer to "struct ccs_policy_namespace". 2415 * 2416 * Returns nothing. 2417 */ 2418 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns) 2419 { 2420 unsigned int idx; 2421 for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++) 2422 INIT_LIST_HEAD(&ns->acl_group[idx]); 2423 for (idx = 0; idx < CCS_MAX_GROUP; idx++) 2424 INIT_LIST_HEAD(&ns->group_list[idx]); 2425 for (idx = 0; idx < CCS_MAX_POLICY; idx++) 2426 INIT_LIST_HEAD(&ns->policy_list[idx]); 2427 ns->profile_version = 20200505; 2428 ccs_namespace_enabled = !list_empty(&ccs_namespace_list); 2429 list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list); 2430 } 2431 2432 /** 2433 * ccs_print_namespace - Print namespace header. 2434 * 2435 * @head: Pointer to "struct ccs_io_buffer". 2436 * 2437 * Returns nothing. 2438 */ 2439 static void ccs_print_namespace(struct ccs_io_buffer *head) 2440 { 2441 if (!ccs_namespace_enabled) 2442 return; 2443 ccs_set_string(head, 2444 container_of(head->r.ns, struct ccs_policy_namespace, 2445 namespace_list)->name); 2446 ccs_set_space(head); 2447 } 2448 2449 /** 2450 * ccs_assign_profile - Create a new profile. 2451 * 2452 * @ns: Pointer to "struct ccs_policy_namespace". 2453 * @profile: Profile number to create. 2454 * 2455 * Returns pointer to "struct ccs_profile" on success, NULL otherwise. 2456 */ 2457 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns, 2458 const unsigned int profile) 2459 { 2460 struct ccs_profile *ptr; 2461 struct ccs_profile *entry; 2462 if (profile >= CCS_MAX_PROFILES) 2463 return NULL; 2464 ptr = ns->profile_ptr[profile]; 2465 if (ptr) 2466 return ptr; 2467 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS); 2468 if (mutex_lock_interruptible(&ccs_policy_lock)) 2469 goto out; 2470 ptr = ns->profile_ptr[profile]; 2471 if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) { 2472 ptr = entry; 2473 ptr->default_config = CCS_CONFIG_DISABLED | 2474 CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG; 2475 memset(ptr->config, CCS_CONFIG_USE_DEFAULT, 2476 sizeof(ptr->config)); 2477 ptr->pref[CCS_PREF_MAX_AUDIT_LOG] = 2478 CONFIG_CCSECURITY_MAX_AUDIT_LOG; 2479 ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] = 2480 CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY; 2481 mb(); /* Avoid out-of-order execution. */ 2482 ns->profile_ptr[profile] = ptr; 2483 entry = NULL; 2484 } 2485 mutex_unlock(&ccs_policy_lock); 2486 out: 2487 kfree(entry); 2488 return ptr; 2489 } 2490 2491 /** 2492 * ccs_check_profile - Check all profiles currently assigned to domains are defined. 2493 * 2494 * Returns nothing. 2495 */ 2496 static void ccs_check_profile(void) 2497 { 2498 struct ccs_domain_info *domain; 2499 const int idx = ccs_read_lock(); 2500 ccs_policy_loaded = true; 2501 printk(KERN_INFO "CCSecurity: 1.8.11 2024/07/15\n"); 2502 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 2503 const u8 profile = domain->profile; 2504 struct ccs_policy_namespace *ns = domain->ns; 2505 if (ns->profile_version == 20100903 || 2506 ns->profile_version == 20150505) { 2507 static bool done; 2508 if (!done) 2509 printk(KERN_INFO "Converting profile version " 2510 "from %u to %u.\n", ns->profile_version, 2511 20200505); 2512 done = true; 2513 ns->profile_version = 20200505; 2514 } 2515 if (ns->profile_version != 20200505) 2516 printk(KERN_ERR 2517 "Profile version %u is not supported.\n", 2518 ns->profile_version); 2519 else if (!ns->profile_ptr[profile]) 2520 printk(KERN_ERR 2521 "Profile %u (used by '%s') is not defined.\n", 2522 profile, domain->domainname->name); 2523 else 2524 continue; 2525 printk(KERN_ERR 2526 "Userland tools for TOMOYO 1.8 must be installed and " 2527 "policy must be initialized.\n"); 2528 printk(KERN_ERR "Please see https://tomoyo.sourceforge.net/1.8/ " 2529 "for more information.\n"); 2530 panic("STOP!"); 2531 } 2532 ccs_read_unlock(idx); 2533 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2534 } 2535 2536 /** 2537 * ccs_profile - Find a profile. 2538 * 2539 * @profile: Profile number to find. 2540 * 2541 * Returns pointer to "struct ccs_profile". 2542 */ 2543 static struct ccs_profile *ccs_profile(const u8 profile) 2544 { 2545 static struct ccs_profile ccs_null_profile; 2546 struct ccs_profile *ptr = ccs_current_namespace()-> 2547 profile_ptr[profile]; 2548 if (!ptr) 2549 ptr = &ccs_null_profile; 2550 return ptr; 2551 } 2552 2553 /** 2554 * ccs_get_config - Get config for specified profile's specified functionality. 2555 * 2556 * @profile: Profile number. 2557 * @index: Index number of functionality. 2558 * 2559 * Returns config. 2560 * 2561 * First, check for CONFIG::category::functionality. 2562 * If CONFIG::category::functionality is set to use default, then check 2563 * CONFIG::category. If CONFIG::category is set to use default, then use 2564 * CONFIG. CONFIG cannot be set to use default. 2565 */ 2566 u8 ccs_get_config(const u8 profile, const u8 index) 2567 { 2568 u8 config; 2569 const struct ccs_profile *p; 2570 if (!ccs_policy_loaded) 2571 return CCS_CONFIG_DISABLED; 2572 p = ccs_profile(profile); 2573 config = p->config[index]; 2574 if (config == CCS_CONFIG_USE_DEFAULT) 2575 config = p->config[ccs_index2category[index] 2576 + CCS_MAX_MAC_INDEX]; 2577 if (config == CCS_CONFIG_USE_DEFAULT) 2578 config = p->default_config; 2579 return config; 2580 } 2581 2582 /** 2583 * ccs_find_yesno - Find values for specified keyword. 2584 * 2585 * @string: String to check. 2586 * @find: Name of keyword. 2587 * 2588 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise. 2589 */ 2590 static s8 ccs_find_yesno(const char *string, const char *find) 2591 { 2592 const char *cp = strstr(string, find); 2593 if (cp) { 2594 cp += strlen(find); 2595 if (!strncmp(cp, "=yes", 4)) 2596 return 1; 2597 else if (!strncmp(cp, "=no", 3)) 2598 return 0; 2599 } 2600 return -1; 2601 } 2602 2603 /** 2604 * ccs_set_uint - Set value for specified preference. 2605 * 2606 * @i: Pointer to "unsigned int". 2607 * @string: String to check. 2608 * @find: Name of keyword. 2609 * 2610 * Returns nothing. 2611 */ 2612 static void ccs_set_uint(unsigned int *i, const char *string, const char *find) 2613 { 2614 const char *cp = strstr(string, find); 2615 if (cp) 2616 sscanf(cp + strlen(find), "=%u", i); 2617 } 2618 2619 /** 2620 * ccs_str_starts - Check whether the given string starts with the given keyword. 2621 * 2622 * @src: Pointer to pointer to the string. 2623 * @find: Pointer to the keyword. 2624 * 2625 * Returns true if @src starts with @find, false otherwise. 2626 * 2627 * The @src is updated to point the first character after the @find 2628 * if @src starts with @find. 2629 */ 2630 static bool ccs_str_starts(char **src, const char *find) 2631 { 2632 const int len = strlen(find); 2633 char *tmp = *src; 2634 if (strncmp(tmp, find, len)) 2635 return false; 2636 tmp += len; 2637 *src = tmp; 2638 return true; 2639 } 2640 2641 /** 2642 * ccs_print_group - Print group's name. 2643 * 2644 * @head: Pointer to "struct ccs_io_buffer". 2645 * @group: Pointer to "struct ccsgroup". Maybe NULL. 2646 * 2647 * Returns true if @group is not NULL. false otherwise. 2648 */ 2649 static bool ccs_print_group(struct ccs_io_buffer *head, 2650 const struct ccs_group *group) 2651 { 2652 if (group) { 2653 ccs_set_string(head, "@"); 2654 ccs_set_string(head, group->group_name->name); 2655 return true; 2656 } 2657 return false; 2658 } 2659 2660 /** 2661 * ccs_set_mode - Set mode for specified profile. 2662 * 2663 * @name: Name of functionality. 2664 * @value: Mode for @name. 2665 * @profile: Pointer to "struct ccs_profile". 2666 * 2667 * Returns 0 on success, negative value otherwise. 2668 */ 2669 static int ccs_set_mode(char *name, const char *value, 2670 struct ccs_profile *profile) 2671 { 2672 u8 i; 2673 u8 config; 2674 if (!strcmp(name, "CONFIG")) { 2675 i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX; 2676 config = profile->default_config; 2677 } else if (ccs_str_starts(&name, "CONFIG::")) { 2678 config = 0; 2679 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX; 2680 i++) { 2681 int len = 0; 2682 if (i < CCS_MAX_MAC_INDEX) { 2683 const u8 c = ccs_index2category[i]; 2684 const char *category = 2685 ccs_category_keywords[c]; 2686 len = strlen(category); 2687 if (strncmp(name, category, len) || 2688 name[len++] != ':' || name[len++] != ':') 2689 continue; 2690 } 2691 if (strcmp(name + len, ccs_mac_keywords[i])) 2692 continue; 2693 config = profile->config[i]; 2694 break; 2695 } 2696 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX) 2697 return -EINVAL; 2698 } else { 2699 return -EINVAL; 2700 } 2701 if (strstr(value, "use_default")) { 2702 config = CCS_CONFIG_USE_DEFAULT; 2703 } else { 2704 u8 mode; 2705 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++) 2706 if (strstr(value, ccs_mode[mode])) 2707 /* 2708 * Update lower 3 bits in order to distinguish 2709 * 'config' from 'CCS_CONFIG_USE_DEFAULT'. 2710 */ 2711 config = (config & ~7) | mode; 2712 if (config != CCS_CONFIG_USE_DEFAULT) { 2713 switch (ccs_find_yesno(value, "grant_log")) { 2714 case 1: 2715 config |= CCS_CONFIG_WANT_GRANT_LOG; 2716 break; 2717 case 0: 2718 config &= ~CCS_CONFIG_WANT_GRANT_LOG; 2719 break; 2720 } 2721 switch (ccs_find_yesno(value, "reject_log")) { 2722 case 1: 2723 config |= CCS_CONFIG_WANT_REJECT_LOG; 2724 break; 2725 case 0: 2726 config &= ~CCS_CONFIG_WANT_REJECT_LOG; 2727 break; 2728 } 2729 } 2730 } 2731 if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX) 2732 profile->config[i] = config; 2733 else if (config != CCS_CONFIG_USE_DEFAULT) 2734 profile->default_config = config; 2735 return 0; 2736 } 2737 2738 /** 2739 * ccs_write_profile - Write profile table. 2740 * 2741 * @head: Pointer to "struct ccs_io_buffer". 2742 * 2743 * Returns 0 on success, negative value otherwise. 2744 */ 2745 static int ccs_write_profile(struct ccs_io_buffer *head) 2746 { 2747 char *data = head->write_buf; 2748 unsigned int i; 2749 char *cp; 2750 struct ccs_profile *profile; 2751 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) 2752 == 1) 2753 return 0; 2754 i = simple_strtoul(data, &cp, 10); 2755 if (*cp != '-') 2756 return -EINVAL; 2757 data = cp + 1; 2758 profile = ccs_assign_profile(head->w.ns, i); 2759 if (!profile) 2760 return -EINVAL; 2761 cp = strchr(data, '='); 2762 if (!cp) 2763 return -EINVAL; 2764 *cp++ = '\0'; 2765 if (!strcmp(data, "COMMENT")) { 2766 static DEFINE_SPINLOCK(lock); 2767 const struct ccs_path_info *new_comment = ccs_get_name(cp); 2768 const struct ccs_path_info *old_comment; 2769 if (!new_comment) 2770 return -ENOMEM; 2771 spin_lock(&lock); 2772 old_comment = profile->comment; 2773 profile->comment = new_comment; 2774 spin_unlock(&lock); 2775 ccs_put_name(old_comment); 2776 return 0; 2777 } 2778 if (!strcmp(data, "PREFERENCE")) { 2779 for (i = 0; i < CCS_MAX_PREF; i++) 2780 ccs_set_uint(&profile->pref[i], cp, 2781 ccs_pref_keywords[i]); 2782 return 0; 2783 } 2784 return ccs_set_mode(data, cp, profile); 2785 } 2786 2787 /** 2788 * ccs_print_config - Print mode for specified functionality. 2789 * 2790 * @head: Pointer to "struct ccs_io_buffer". 2791 * @config: Mode for that functionality. 2792 * 2793 * Returns nothing. 2794 * 2795 * Caller prints functionality's name. 2796 */ 2797 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config) 2798 { 2799 ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n", 2800 ccs_mode[config & 3], 2801 ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG), 2802 ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG)); 2803 } 2804 2805 /** 2806 * ccs_read_profile - Read profile table. 2807 * 2808 * @head: Pointer to "struct ccs_io_buffer". 2809 * 2810 * Returns nothing. 2811 */ 2812 static void ccs_read_profile(struct ccs_io_buffer *head) 2813 { 2814 u8 index; 2815 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 2816 namespace_list); 2817 const struct ccs_profile *profile; 2818 if (head->r.eof) 2819 return; 2820 next: 2821 index = head->r.index; 2822 profile = ns->profile_ptr[index]; 2823 switch (head->r.step) { 2824 case 0: 2825 ccs_print_namespace(head); 2826 ccs_io_printf(head, "PROFILE_VERSION=%u\n", 2827 ns->profile_version); 2828 head->r.step++; 2829 break; 2830 case 1: 2831 for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++) 2832 if (ns->profile_ptr[head->r.index]) 2833 break; 2834 if (head->r.index == CCS_MAX_PROFILES) { 2835 head->r.eof = true; 2836 return; 2837 } 2838 head->r.step++; 2839 break; 2840 case 2: 2841 { 2842 u8 i; 2843 const struct ccs_path_info *comment = profile->comment; 2844 ccs_print_namespace(head); 2845 ccs_io_printf(head, "%u-COMMENT=", index); 2846 ccs_set_string(head, comment ? comment->name : ""); 2847 ccs_set_lf(head); 2848 ccs_print_namespace(head); 2849 ccs_io_printf(head, "%u-PREFERENCE={ ", index); 2850 for (i = 0; i < CCS_MAX_PREF; i++) 2851 ccs_io_printf(head, "%s=%u ", 2852 ccs_pref_keywords[i], 2853 profile->pref[i]); 2854 ccs_set_string(head, "}\n"); 2855 head->r.step++; 2856 } 2857 break; 2858 case 3: 2859 { 2860 ccs_print_namespace(head); 2861 ccs_io_printf(head, "%u-%s", index, "CONFIG"); 2862 ccs_print_config(head, profile->default_config); 2863 head->r.bit = 0; 2864 head->r.step++; 2865 } 2866 break; 2867 case 4: 2868 for ( ; head->r.bit < CCS_MAX_MAC_INDEX 2869 + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { 2870 const u8 i = head->r.bit; 2871 const u8 config = profile->config[i]; 2872 if (config == CCS_CONFIG_USE_DEFAULT) 2873 continue; 2874 ccs_print_namespace(head); 2875 if (i < CCS_MAX_MAC_INDEX) 2876 ccs_io_printf(head, "%u-CONFIG::%s::%s", index, 2877 ccs_category_keywords 2878 [ccs_index2category[i]], 2879 ccs_mac_keywords[i]); 2880 else 2881 ccs_io_printf(head, "%u-CONFIG::%s", index, 2882 ccs_mac_keywords[i]); 2883 ccs_print_config(head, config); 2884 head->r.bit++; 2885 break; 2886 } 2887 if (head->r.bit == CCS_MAX_MAC_INDEX 2888 + CCS_MAX_MAC_CATEGORY_INDEX) { 2889 head->r.index++; 2890 head->r.step = 1; 2891 } 2892 break; 2893 } 2894 if (ccs_flush(head)) 2895 goto next; 2896 } 2897 2898 /** 2899 * ccs_update_policy - Update an entry for exception policy. 2900 * 2901 * @size: Size of new entry in bytes. 2902 * @param: Pointer to "struct ccs_acl_param". 2903 * 2904 * Returns 0 on success, negative value otherwise. 2905 * 2906 * Caller holds ccs_read_lock(). 2907 */ 2908 static int ccs_update_policy(const int size, struct ccs_acl_param *param) 2909 { 2910 struct ccs_acl_head *new_entry = ¶m->e.acl_head; 2911 int error = param->is_delete ? -ENOENT : -ENOMEM; 2912 struct ccs_acl_head *entry; 2913 struct list_head *list = param->list; 2914 BUG_ON(size < sizeof(*entry)); 2915 if (mutex_lock_interruptible(&ccs_policy_lock)) 2916 return -ENOMEM; 2917 list_for_each_entry_srcu(entry, list, list, &ccs_ss) { 2918 if (entry->is_deleted == CCS_GC_IN_PROGRESS) 2919 continue; 2920 if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry))) 2921 continue; 2922 entry->is_deleted = param->is_delete; 2923 error = 0; 2924 break; 2925 } 2926 if (error && !param->is_delete) { 2927 entry = ccs_commit_ok(new_entry, size); 2928 if (entry) { 2929 list_add_tail_rcu(&entry->list, list); 2930 error = 0; 2931 } 2932 } 2933 mutex_unlock(&ccs_policy_lock); 2934 return error; 2935 } 2936 2937 /** 2938 * ccs_update_manager_entry - Add a manager entry. 2939 * 2940 * @manager: The path to manager or the domainnamme. 2941 * @is_delete: True if it is a delete request. 2942 * 2943 * Returns 0 on success, negative value otherwise. 2944 */ 2945 static int ccs_update_manager_entry(const char *manager, 2946 const bool is_delete) 2947 { 2948 struct ccs_acl_param param = { 2949 /* .ns = &ccs_kernel_namespace, */ 2950 .is_delete = is_delete, 2951 .list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER], 2952 }; 2953 struct ccs_manager *e = ¶m.e.manager; 2954 int error = is_delete ? -ENOENT : -ENOMEM; 2955 /* Forced zero clear for using memcmp() at ccs_update_policy(). */ 2956 memset(¶m.e, 0, sizeof(param.e)); 2957 if (!ccs_correct_domain(manager) && !ccs_correct_word(manager)) 2958 return -EINVAL; 2959 e->manager = ccs_get_name(manager); 2960 if (e->manager) { 2961 error = ccs_update_policy(sizeof(*e), ¶m); 2962 ccs_put_name(e->manager); 2963 } 2964 return error; 2965 } 2966 2967 /** 2968 * ccs_write_manager - Write manager policy. 2969 * 2970 * @head: Pointer to "struct ccs_io_buffer". 2971 * 2972 * Returns 0 on success, negative value otherwise. 2973 */ 2974 static int ccs_write_manager(struct ccs_io_buffer *head) 2975 { 2976 const char *data = head->write_buf; 2977 if (!strcmp(data, "manage_by_non_root")) { 2978 ccs_manage_by_non_root = !head->w.is_delete; 2979 return 0; 2980 } 2981 return ccs_update_manager_entry(data, head->w.is_delete); 2982 } 2983 2984 /** 2985 * ccs_read_manager - Read manager policy. 2986 * 2987 * @head: Pointer to "struct ccs_io_buffer". 2988 * 2989 * Returns nothing. 2990 * 2991 * Caller holds ccs_read_lock(). 2992 */ 2993 static void ccs_read_manager(struct ccs_io_buffer *head) 2994 { 2995 if (head->r.eof) 2996 return; 2997 list_for_each_cookie(head->r.acl, &ccs_kernel_namespace. 2998 policy_list[CCS_ID_MANAGER]) { 2999 struct ccs_manager *ptr = 3000 list_entry(head->r.acl, typeof(*ptr), head.list); 3001 if (ptr->head.is_deleted) 3002 continue; 3003 if (!ccs_flush(head)) 3004 return; 3005 ccs_set_string(head, ptr->manager->name); 3006 ccs_set_lf(head); 3007 } 3008 head->r.eof = true; 3009 } 3010 3011 /** 3012 * ccs_manager - Check whether the current process is a policy manager. 3013 * 3014 * Returns true if the current process is permitted to modify policy 3015 * via /proc/ccs/ interface. 3016 * 3017 * Caller holds ccs_read_lock(). 3018 */ 3019 static bool ccs_manager(void) 3020 { 3021 struct ccs_manager *ptr; 3022 struct ccs_path_info exe; 3023 struct ccs_security *task = ccs_current_security(); 3024 const struct ccs_path_info *domainname 3025 = ccs_current_domain()->domainname; 3026 bool found = false; 3027 if (!ccs_policy_loaded) 3028 return true; 3029 if (task->ccs_flags & CCS_TASK_IS_MANAGER) 3030 return true; 3031 if (!ccs_manage_by_non_root && 3032 (!uid_eq(current_uid(), GLOBAL_ROOT_UID) || 3033 !uid_eq(current_euid(), GLOBAL_ROOT_UID))) 3034 return false; 3035 exe.name = ccs_get_exe(); 3036 if (!exe.name) 3037 return false; 3038 ccs_fill_path_info(&exe); 3039 list_for_each_entry_srcu(ptr, &ccs_kernel_namespace. 3040 policy_list[CCS_ID_MANAGER], head.list, 3041 &ccs_ss) { 3042 if (ptr->head.is_deleted) 3043 continue; 3044 if (ccs_pathcmp(domainname, ptr->manager) && 3045 ccs_pathcmp(&exe, ptr->manager)) 3046 continue; 3047 /* Set manager flag. */ 3048 task->ccs_flags |= CCS_TASK_IS_MANAGER; 3049 found = true; 3050 break; 3051 } 3052 if (!found) { /* Reduce error messages. */ 3053 static pid_t ccs_last_pid; 3054 const pid_t pid = current->pid; 3055 if (ccs_last_pid != pid) { 3056 printk(KERN_WARNING "%s ( %s ) is not permitted to " 3057 "update policies.\n", domainname->name, 3058 exe.name); 3059 ccs_last_pid = pid; 3060 } 3061 } 3062 kfree(exe.name); 3063 return found; 3064 } 3065 3066 /** 3067 * ccs_find_domain - Find a domain by the given name. 3068 * 3069 * @domainname: The domainname to find. 3070 * 3071 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise. 3072 * 3073 * Caller holds ccs_read_lock(). 3074 */ 3075 static struct ccs_domain_info *ccs_find_domain(const char *domainname) 3076 { 3077 struct ccs_domain_info *domain; 3078 struct ccs_path_info name; 3079 name.name = domainname; 3080 ccs_fill_path_info(&name); 3081 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 3082 if (!domain->is_deleted && 3083 !ccs_pathcmp(&name, domain->domainname)) 3084 return domain; 3085 } 3086 return NULL; 3087 } 3088 3089 /** 3090 * ccs_select_domain - Parse select command. 3091 * 3092 * @head: Pointer to "struct ccs_io_buffer". 3093 * @data: String to parse. 3094 * 3095 * Returns true on success, false otherwise. 3096 * 3097 * Caller holds ccs_read_lock(). 3098 */ 3099 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data) 3100 { 3101 unsigned int pid; 3102 struct ccs_domain_info *domain = NULL; 3103 bool global_pid = false; 3104 if (strncmp(data, "select ", 7)) 3105 return false; 3106 data += 7; 3107 if (sscanf(data, "pid=%u", &pid) == 1 || 3108 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 3109 struct task_struct *p; 3110 ccs_tasklist_lock(); 3111 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 3112 if (global_pid) 3113 p = ccsecurity_exports.find_task_by_pid_ns(pid, 3114 &init_pid_ns); 3115 else 3116 p = ccsecurity_exports.find_task_by_vpid(pid); 3117 #else 3118 p = find_task_by_pid(pid); 3119 #endif 3120 if (p) 3121 domain = ccs_task_domain(p); 3122 ccs_tasklist_unlock(); 3123 } else if (!strncmp(data, "domain=", 7)) { 3124 if (*(data + 7) == '<') 3125 domain = ccs_find_domain(data + 7); 3126 } else if (sscanf(data, "Q=%u", &pid) == 1) { 3127 domain = ccs_find_domain_by_qid(pid); 3128 } else 3129 return false; 3130 head->w.domain = domain; 3131 /* Accessing read_buf is safe because head->io_sem is held. */ 3132 if (!head->read_buf) 3133 return true; /* Do nothing if open(O_WRONLY). */ 3134 memset(&head->r, 0, sizeof(head->r)); 3135 head->r.print_this_domain_only = true; 3136 if (domain) 3137 head->r.domain = &domain->list; 3138 else 3139 head->r.eof = true; 3140 ccs_io_printf(head, "# select %s\n", data); 3141 if (domain && domain->is_deleted) 3142 ccs_set_string(head, "# This is a deleted domain.\n"); 3143 return true; 3144 } 3145 3146 /** 3147 * ccs_update_acl - Update "struct ccs_acl_info" entry. 3148 * 3149 * @size: Size of new entry in bytes. 3150 * @param: Pointer to "struct ccs_acl_param". 3151 * 3152 * Returns 0 on success, negative value otherwise. 3153 * 3154 * Caller holds ccs_read_lock(). 3155 */ 3156 static int ccs_update_acl(const int size, struct ccs_acl_param *param) 3157 { 3158 struct ccs_acl_info *new_entry = ¶m->e.acl_info; 3159 const bool is_delete = param->is_delete; 3160 int error = is_delete ? -ENOENT : -ENOMEM; 3161 struct ccs_acl_info *entry; 3162 struct list_head * const list = param->list; 3163 BUG_ON(size < sizeof(*entry)); 3164 if (param->data[0]) { 3165 /* 3166 * Domain transition preference is allowed for only 3167 * "file execute"/"task auto_execute_handler"/ 3168 * "task denied_auto_execute_handler" entries. 3169 */ 3170 const bool pref = (new_entry->type == CCS_TYPE_PATH_ACL && 3171 new_entry->perm == 1 << CCS_TYPE_EXECUTE) 3172 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3173 || new_entry->type == CCS_TYPE_AUTO_EXECUTE_HANDLER 3174 || new_entry->type == CCS_TYPE_DENIED_EXECUTE_HANDLER 3175 #endif 3176 ; 3177 new_entry->cond = ccs_get_condition(param, pref); 3178 if (!new_entry->cond) 3179 return error; 3180 } 3181 if (mutex_lock_interruptible(&ccs_policy_lock)) 3182 return -ENOMEM; 3183 list_for_each_entry_srcu(entry, list, list, &ccs_ss) { 3184 if (entry->is_deleted == CCS_GC_IN_PROGRESS) 3185 continue; 3186 if (entry->type != new_entry->type || 3187 entry->cond != new_entry->cond || 3188 memcmp(entry + 1, new_entry + 1, size - sizeof(*entry))) 3189 continue; 3190 if (is_delete) 3191 entry->perm &= ~new_entry->perm; 3192 else 3193 entry->perm |= new_entry->perm; 3194 entry->is_deleted = !entry->perm; 3195 error = 0; 3196 break; 3197 } 3198 if (error && !is_delete) { 3199 entry = ccs_commit_ok(new_entry, size); 3200 if (entry) { 3201 list_add_tail_rcu(&entry->list, list); 3202 error = 0; 3203 } 3204 } 3205 mutex_unlock(&ccs_policy_lock); 3206 return error; 3207 } 3208 3209 /** 3210 * ccs_permstr - Find permission keywords. 3211 * 3212 * @string: String representation for permissions in foo/bar/buz format. 3213 * @keyword: Keyword to find from @string/ 3214 * 3215 * Returns true if @keyword was found in @string, false otherwise. 3216 * 3217 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2. 3218 */ 3219 static bool ccs_permstr(const char *string, const char *keyword) 3220 { 3221 const char *cp = strstr(string, keyword); 3222 if (cp) 3223 return cp == string || *(cp - 1) == '/'; 3224 return false; 3225 } 3226 3227 /** 3228 * ccs_write_task - Update task related list. 3229 * 3230 * @param: Pointer to "struct ccs_acl_param". 3231 * 3232 * Returns 0 on success, negative value otherwise. 3233 * 3234 * Caller holds ccs_read_lock(). 3235 */ 3236 static int ccs_write_task(struct ccs_acl_param *param) 3237 { 3238 int error; 3239 const bool is_auto = ccs_str_starts(¶m->data, 3240 "auto_domain_transition "); 3241 if (!is_auto && !ccs_str_starts(¶m->data, 3242 "manual_domain_transition ")) { 3243 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3244 struct ccs_handler_acl *e = ¶m->e.handler_acl; 3245 char *handler; 3246 if (ccs_str_starts(¶m->data, "auto_execute_handler ")) 3247 e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER; 3248 else if (ccs_str_starts(¶m->data, 3249 "denied_execute_handler ")) 3250 e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER; 3251 else 3252 return -EINVAL; 3253 handler = ccs_read_token(param); 3254 if (*handler != '/' || !ccs_correct_path(handler)) 3255 return -EINVAL; 3256 e->handler = ccs_get_name(handler); 3257 if (!e->handler) 3258 return -ENOMEM; 3259 if (e->handler->is_patterned) 3260 return -EINVAL; /* No patterns allowed. */ 3261 return ccs_update_acl(sizeof(*e), param); 3262 #else 3263 error = -EINVAL; 3264 #endif 3265 } else { 3266 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 3267 struct ccs_task_acl *e = ¶m->e.task_acl; 3268 e->head.type = is_auto ? 3269 CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL; 3270 e->domainname = ccs_get_domainname(param); 3271 if (!e->domainname) 3272 return -EINVAL; 3273 return ccs_update_acl(sizeof(*e), param); 3274 #else 3275 error = -EINVAL; 3276 #endif 3277 } 3278 return error; 3279 } 3280 3281 #ifdef CONFIG_CCSECURITY_NETWORK 3282 3283 /** 3284 * ccs_write_inet_network - Write "struct ccs_inet_acl" list. 3285 * 3286 * @param: Pointer to "struct ccs_acl_param". 3287 * 3288 * Returns 0 on success, negative value otherwise. 3289 * 3290 * Caller holds ccs_read_lock(). 3291 */ 3292 static int ccs_write_inet_network(struct ccs_acl_param *param) 3293 { 3294 struct ccs_inet_acl *e = ¶m->e.inet_acl; 3295 u8 type; 3296 const char *protocol = ccs_read_token(param); 3297 const char *operation = ccs_read_token(param); 3298 e->head.type = CCS_TYPE_INET_ACL; 3299 for (type = 0; type < CCS_SOCK_MAX; type++) 3300 if (!strcmp(protocol, ccs_proto_keyword[type])) 3301 break; 3302 if (type == CCS_SOCK_MAX) 3303 return -EINVAL; 3304 e->protocol = type; 3305 e->head.perm = 0; 3306 for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++) 3307 if (ccs_permstr(operation, ccs_socket_keyword[type])) 3308 e->head.perm |= 1 << type; 3309 if (!e->head.perm) 3310 return -EINVAL; 3311 if (param->data[0] == '@') { 3312 param->data++; 3313 e->address.group = ccs_get_group(param, CCS_ADDRESS_GROUP); 3314 if (!e->address.group) 3315 return -ENOMEM; 3316 } else { 3317 if (!ccs_parse_ipaddr_union(param, &e->address)) 3318 return -EINVAL; 3319 } 3320 if (!ccs_parse_number_union(param, &e->port) || 3321 e->port.values[1] > 65535) 3322 return -EINVAL; 3323 return ccs_update_acl(sizeof(*e), param); 3324 } 3325 3326 /** 3327 * ccs_write_unix_network - Write "struct ccs_unix_acl" list. 3328 * 3329 * @param: Pointer to "struct ccs_acl_param". 3330 * 3331 * Returns 0 on success, negative value otherwise. 3332 */ 3333 static int ccs_write_unix_network(struct ccs_acl_param *param) 3334 { 3335 struct ccs_unix_acl *e = ¶m->e.unix_acl; 3336 u8 type; 3337 const char *protocol = ccs_read_token(param); 3338 const char *operation = ccs_read_token(param); 3339 e->head.type = CCS_TYPE_UNIX_ACL; 3340 for (type = 0; type < CCS_SOCK_MAX; type++) 3341 if (!strcmp(protocol, ccs_proto_keyword[type])) 3342 break; 3343 if (type == CCS_SOCK_MAX) 3344 return -EINVAL; 3345 e->protocol = type; 3346 e->head.perm = 0; 3347 for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++) 3348 if (ccs_permstr(operation, ccs_socket_keyword[type])) 3349 e->head.perm |= 1 << type; 3350 if (!e->head.perm) 3351 return -EINVAL; 3352 if (!ccs_parse_name_union(param, &e->name)) 3353 return -EINVAL; 3354 return ccs_update_acl(sizeof(*e), param); 3355 } 3356 3357 #endif 3358 3359 /** 3360 * ccs_write_file - Update file related list. 3361 * 3362 * @param: Pointer to "struct ccs_acl_param". 3363 * 3364 * Returns 0 on success, negative value otherwise. 3365 * 3366 * Caller holds ccs_read_lock(). 3367 */ 3368 static int ccs_write_file(struct ccs_acl_param *param) 3369 { 3370 u16 perm = 0; 3371 u8 type; 3372 const char *operation = ccs_read_token(param); 3373 for (type = 0; type < CCS_MAX_PATH_OPERATION; type++) 3374 if (ccs_permstr(operation, ccs_path_keyword[type])) 3375 perm |= 1 << type; 3376 if (perm) { 3377 struct ccs_path_acl *e = ¶m->e.path_acl; 3378 e->head.type = CCS_TYPE_PATH_ACL; 3379 e->head.perm = perm; 3380 if (!ccs_parse_name_union(param, &e->name)) 3381 return -EINVAL; 3382 return ccs_update_acl(sizeof(*e), param); 3383 } 3384 for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++) 3385 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]])) 3386 perm |= 1 << type; 3387 if (perm) { 3388 struct ccs_path2_acl *e = ¶m->e.path2_acl; 3389 e->head.type = CCS_TYPE_PATH2_ACL; 3390 e->head.perm = perm; 3391 if (!ccs_parse_name_union(param, &e->name1) || 3392 !ccs_parse_name_union(param, &e->name2)) 3393 return -EINVAL; 3394 return ccs_update_acl(sizeof(*e), param); 3395 } 3396 for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++) 3397 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]])) 3398 perm |= 1 << type; 3399 if (perm) { 3400 struct ccs_path_number_acl *e = ¶m->e.path_number_acl; 3401 e->head.type = CCS_TYPE_PATH_NUMBER_ACL; 3402 e->head.perm = perm; 3403 if (!ccs_parse_name_union(param, &e->name) || 3404 !ccs_parse_number_union(param, &e->number)) 3405 return -EINVAL; 3406 return ccs_update_acl(sizeof(*e), param); 3407 } 3408 for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++) 3409 if (ccs_permstr(operation, 3410 ccs_mac_keywords[ccs_pnnn2mac[type]])) 3411 perm |= 1 << type; 3412 if (perm) { 3413 struct ccs_mkdev_acl *e = ¶m->e.mkdev_acl; 3414 e->head.type = CCS_TYPE_MKDEV_ACL; 3415 e->head.perm = perm; 3416 if (!ccs_parse_name_union(param, &e->name) || 3417 !ccs_parse_number_union(param, &e->mode) || 3418 !ccs_parse_number_union(param, &e->major) || 3419 !ccs_parse_number_union(param, &e->minor)) 3420 return -EINVAL; 3421 return ccs_update_acl(sizeof(*e), param); 3422 } 3423 if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) { 3424 struct ccs_mount_acl *e = ¶m->e.mount_acl; 3425 e->head.type = CCS_TYPE_MOUNT_ACL; 3426 if (!ccs_parse_name_union(param, &e->dev_name) || 3427 !ccs_parse_name_union(param, &e->dir_name) || 3428 !ccs_parse_name_union(param, &e->fs_type) || 3429 !ccs_parse_number_union(param, &e->flags)) 3430 return -EINVAL; 3431 return ccs_update_acl(sizeof(*e), param); 3432 } 3433 return -EINVAL; 3434 } 3435 3436 #ifdef CONFIG_CCSECURITY_MISC 3437 3438 /** 3439 * ccs_write_misc - Update environment variable list. 3440 * 3441 * @param: Pointer to "struct ccs_acl_param". 3442 * 3443 * Returns 0 on success, negative value otherwise. 3444 */ 3445 static int ccs_write_misc(struct ccs_acl_param *param) 3446 { 3447 if (ccs_str_starts(¶m->data, "env ")) { 3448 struct ccs_env_acl *e = ¶m->e.env_acl; 3449 const char *data = ccs_read_token(param); 3450 e->head.type = CCS_TYPE_ENV_ACL; 3451 if (!ccs_correct_word(data) || strchr(data, '=')) 3452 return -EINVAL; 3453 e->env = ccs_get_name(data); 3454 if (!e->env) 3455 return -ENOMEM; 3456 return ccs_update_acl(sizeof(*e), param); 3457 } 3458 return -EINVAL; 3459 } 3460 3461 #endif 3462 3463 #ifdef CONFIG_CCSECURITY_IPC 3464 3465 /** 3466 * ccs_write_ipc - Update "struct ccs_signal_acl" list. 3467 * 3468 * @param: Pointer to "struct ccs_acl_param". 3469 * 3470 * Returns 0 on success, negative value otherwise. 3471 */ 3472 static int ccs_write_ipc(struct ccs_acl_param *param) 3473 { 3474 struct ccs_signal_acl *e = ¶m->e.signal_acl; 3475 e->head.type = CCS_TYPE_SIGNAL_ACL; 3476 if (!ccs_parse_number_union(param, &e->sig)) 3477 return -EINVAL; 3478 e->domainname = ccs_get_domainname(param); 3479 if (!e->domainname) 3480 return -EINVAL; 3481 return ccs_update_acl(sizeof(*e), param); 3482 } 3483 3484 #endif 3485 3486 #ifdef CONFIG_CCSECURITY_CAPABILITY 3487 3488 /** 3489 * ccs_write_capability - Write "struct ccs_capability_acl" list. 3490 * 3491 * @param: Pointer to "struct ccs_acl_param". 3492 * 3493 * Returns 0 on success, negative value otherwise. 3494 * 3495 * Caller holds ccs_read_lock(). 3496 */ 3497 static int ccs_write_capability(struct ccs_acl_param *param) 3498 { 3499 struct ccs_capability_acl *e = ¶m->e.capability_acl; 3500 const char *operation = ccs_read_token(param); 3501 u8 type; 3502 e->head.type = CCS_TYPE_CAPABILITY_ACL; 3503 for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) { 3504 if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]])) 3505 continue; 3506 e->operation = type; 3507 return ccs_update_acl(sizeof(*e), param); 3508 } 3509 return -EINVAL; 3510 } 3511 3512 #endif 3513 3514 /** 3515 * ccs_write_acl - Write "struct ccs_acl_info" list. 3516 * 3517 * @ns: Pointer to "struct ccs_policy_namespace". 3518 * @list: Pointer to "struct list_head". 3519 * @data: Policy to be interpreted. 3520 * @is_delete: True if it is a delete request. 3521 * 3522 * Returns 0 on success, negative value otherwise. 3523 * 3524 * Caller holds ccs_read_lock(). 3525 */ 3526 static int ccs_write_acl(struct ccs_policy_namespace *ns, 3527 struct list_head *list, char *data, 3528 const bool is_delete) 3529 { 3530 struct ccs_acl_param param = { 3531 .ns = ns, 3532 .list = list, 3533 .data = data, 3534 .is_delete = is_delete, 3535 }; 3536 static const struct { 3537 const char *keyword; 3538 int (*write) (struct ccs_acl_param *); 3539 } ccs_callback[] = { 3540 { "file ", ccs_write_file }, 3541 #ifdef CONFIG_CCSECURITY_NETWORK 3542 { "network inet ", ccs_write_inet_network }, 3543 { "network unix ", ccs_write_unix_network }, 3544 #endif 3545 #ifdef CONFIG_CCSECURITY_MISC 3546 { "misc ", ccs_write_misc }, 3547 #endif 3548 #ifdef CONFIG_CCSECURITY_CAPABILITY 3549 { "capability ", ccs_write_capability }, 3550 #endif 3551 #ifdef CONFIG_CCSECURITY_IPC 3552 { "ipc signal ", ccs_write_ipc }, 3553 #endif 3554 { "task ", ccs_write_task }, 3555 }; 3556 u8 i; 3557 /* Forced zero clear for using memcmp() at ccs_update_acl(). */ 3558 memset(¶m.e, 0, sizeof(param.e)); 3559 param.e.acl_info.perm = 1; 3560 for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) { 3561 int error; 3562 if (!ccs_str_starts(¶m.data, ccs_callback[i].keyword)) 3563 continue; 3564 error = ccs_callback[i].write(¶m); 3565 ccs_del_acl(¶m.e.acl_info.list); 3566 return error; 3567 } 3568 return -EINVAL; 3569 } 3570 3571 /** 3572 * ccs_delete_domain - Delete a domain. 3573 * 3574 * @domainname: The name of domain. 3575 * 3576 * Returns 0. 3577 */ 3578 static int ccs_delete_domain(char *domainname) 3579 { 3580 struct ccs_domain_info *domain; 3581 struct ccs_path_info name; 3582 name.name = domainname; 3583 ccs_fill_path_info(&name); 3584 if (mutex_lock_interruptible(&ccs_policy_lock)) 3585 return 0; 3586 /* Is there an active domain? */ 3587 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 3588 /* Never delete ccs_kernel_domain. */ 3589 if (domain == &ccs_kernel_domain) 3590 continue; 3591 if (domain->is_deleted || 3592 ccs_pathcmp(domain->domainname, &name)) 3593 continue; 3594 domain->is_deleted = true; 3595 break; 3596 } 3597 mutex_unlock(&ccs_policy_lock); 3598 return 0; 3599 } 3600 3601 /** 3602 * ccs_write_domain - Write domain policy. 3603 * 3604 * @head: Pointer to "struct ccs_io_buffer". 3605 * 3606 * Returns 0 on success, negative value otherwise. 3607 * 3608 * Caller holds ccs_read_lock(). 3609 */ 3610 static int ccs_write_domain(struct ccs_io_buffer *head) 3611 { 3612 char *data = head->write_buf; 3613 struct ccs_policy_namespace *ns; 3614 struct ccs_domain_info *domain = head->w.domain; 3615 const bool is_delete = head->w.is_delete; 3616 const bool is_select = !is_delete && ccs_str_starts(&data, "select "); 3617 unsigned int idx; 3618 if (*data == '<') { 3619 domain = NULL; 3620 if (is_delete) 3621 ccs_delete_domain(data); 3622 else if (is_select) 3623 domain = ccs_find_domain(data); 3624 else 3625 domain = ccs_assign_domain(data, false); 3626 head->w.domain = domain; 3627 return 0; 3628 } 3629 if (!domain) 3630 return -EINVAL; 3631 ns = domain->ns; 3632 if (sscanf(data, "use_profile %u\n", &idx) == 1 && 3633 idx < CCS_MAX_PROFILES) { 3634 if (!ccs_policy_loaded || ns->profile_ptr[(u8) idx]) 3635 if (!is_delete) 3636 domain->profile = (u8) idx; 3637 return 0; 3638 } 3639 if (sscanf(data, "use_group %u\n", &idx) == 1 && 3640 idx < CCS_MAX_ACL_GROUPS) { 3641 if (!is_delete) 3642 set_bit(idx, domain->group); 3643 else 3644 clear_bit(idx, domain->group); 3645 return 0; 3646 } 3647 for (idx = 0; idx < CCS_MAX_DOMAIN_INFO_FLAGS; idx++) { 3648 const char *cp = ccs_dif[idx]; 3649 if (strncmp(data, cp, strlen(cp) - 1)) 3650 continue; 3651 domain->flags[idx] = !is_delete; 3652 return 0; 3653 } 3654 return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete); 3655 } 3656 3657 /** 3658 * ccs_print_name_union - Print a ccs_name_union. 3659 * 3660 * @head: Pointer to "struct ccs_io_buffer". 3661 * @ptr: Pointer to "struct ccs_name_union". 3662 * 3663 * Returns nothing. 3664 */ 3665 static void ccs_print_name_union(struct ccs_io_buffer *head, 3666 const struct ccs_name_union *ptr) 3667 { 3668 ccs_set_space(head); 3669 if (!ccs_print_group(head, ptr->group)) 3670 ccs_set_string(head, ptr->filename->name); 3671 } 3672 3673 /** 3674 * ccs_print_name_union_quoted - Print a ccs_name_union with a quote. 3675 * 3676 * @head: Pointer to "struct ccs_io_buffer". 3677 * @ptr: Pointer to "struct ccs_name_union". 3678 * 3679 * Returns nothing. 3680 */ 3681 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head, 3682 const struct ccs_name_union *ptr) 3683 { 3684 if (!ccs_print_group(head, ptr->group)) { 3685 ccs_set_string(head, "\""); 3686 ccs_set_string(head, ptr->filename->name); 3687 ccs_set_string(head, "\""); 3688 } 3689 } 3690 3691 /** 3692 * ccs_print_number_union_nospace - Print a ccs_number_union without a space. 3693 * 3694 * @head: Pointer to "struct ccs_io_buffer". 3695 * @ptr: Pointer to "struct ccs_number_union". 3696 * 3697 * Returns nothing. 3698 */ 3699 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head, 3700 const struct ccs_number_union *ptr) 3701 { 3702 if (!ccs_print_group(head, ptr->group)) { 3703 int i; 3704 unsigned long min = ptr->values[0]; 3705 const unsigned long max = ptr->values[1]; 3706 u8 min_type = ptr->value_type[0]; 3707 const u8 max_type = ptr->value_type[1]; 3708 char buffer[128]; 3709 buffer[0] = '\0'; 3710 for (i = 0; i < 2; i++) { 3711 switch (min_type) { 3712 case CCS_VALUE_TYPE_HEXADECIMAL: 3713 ccs_addprintf(buffer, sizeof(buffer), "0x%lX", 3714 min); 3715 break; 3716 case CCS_VALUE_TYPE_OCTAL: 3717 ccs_addprintf(buffer, sizeof(buffer), "0%lo", 3718 min); 3719 break; 3720 default: 3721 ccs_addprintf(buffer, sizeof(buffer), "%lu", 3722 min); 3723 break; 3724 } 3725 if (min == max && min_type == max_type) 3726 break; 3727 ccs_addprintf(buffer, sizeof(buffer), "-"); 3728 min_type = max_type; 3729 min = max; 3730 } 3731 ccs_io_printf(head, "%s", buffer); 3732 } 3733 } 3734 3735 /** 3736 * ccs_print_number_union - Print a ccs_number_union. 3737 * 3738 * @head: Pointer to "struct ccs_io_buffer". 3739 * @ptr: Pointer to "struct ccs_number_union". 3740 * 3741 * Returns nothing. 3742 */ 3743 static void ccs_print_number_union(struct ccs_io_buffer *head, 3744 const struct ccs_number_union *ptr) 3745 { 3746 ccs_set_space(head); 3747 ccs_print_number_union_nospace(head, ptr); 3748 } 3749 3750 /** 3751 * ccs_print_condition - Print condition part. 3752 * 3753 * @head: Pointer to "struct ccs_io_buffer". 3754 * @cond: Pointer to "struct ccs_condition". 3755 * 3756 * Returns true on success, false otherwise. 3757 */ 3758 static bool ccs_print_condition(struct ccs_io_buffer *head, 3759 const struct ccs_condition *cond) 3760 { 3761 switch (head->r.cond_step) { 3762 case 0: 3763 head->r.cond_index = 0; 3764 head->r.cond_step++; 3765 if (cond->transit && cond->exec_transit) { 3766 ccs_set_space(head); 3767 ccs_set_string(head, cond->transit->name); 3768 } 3769 /* fall through */ 3770 fallthrough; 3771 case 1: 3772 { 3773 const u16 condc = cond->condc; 3774 const struct ccs_condition_element *condp = 3775 (typeof(condp)) (cond + 1); 3776 const struct ccs_number_union *numbers_p = 3777 (typeof(numbers_p)) (condp + condc); 3778 const struct ccs_name_union *names_p = 3779 (typeof(names_p)) 3780 (numbers_p + cond->numbers_count); 3781 const struct ccs_argv *argv = 3782 (typeof(argv)) (names_p + cond->names_count); 3783 const struct ccs_envp *envp = 3784 (typeof(envp)) (argv + cond->argc); 3785 u16 skip; 3786 for (skip = 0; skip < head->r.cond_index; skip++) { 3787 const u8 left = condp->left; 3788 const u8 right = condp->right; 3789 condp++; 3790 switch (left) { 3791 case CCS_ARGV_ENTRY: 3792 argv++; 3793 continue; 3794 case CCS_ENVP_ENTRY: 3795 envp++; 3796 continue; 3797 case CCS_NUMBER_UNION: 3798 numbers_p++; 3799 break; 3800 } 3801 switch (right) { 3802 case CCS_NAME_UNION: 3803 names_p++; 3804 break; 3805 case CCS_NUMBER_UNION: 3806 numbers_p++; 3807 break; 3808 } 3809 } 3810 while (head->r.cond_index < condc) { 3811 const u8 match = condp->equals; 3812 const u8 left = condp->left; 3813 const u8 right = condp->right; 3814 if (!ccs_flush(head)) 3815 return false; 3816 condp++; 3817 head->r.cond_index++; 3818 ccs_set_space(head); 3819 switch (left) { 3820 case CCS_ARGV_ENTRY: 3821 ccs_io_printf(head, 3822 "exec.argv[%lu]%s=\"", 3823 argv->index, 3824 argv->is_not ? "!" : ""); 3825 ccs_set_string(head, 3826 argv->value->name); 3827 ccs_set_string(head, "\""); 3828 argv++; 3829 continue; 3830 case CCS_ENVP_ENTRY: 3831 ccs_set_string(head, "exec.envp[\""); 3832 ccs_set_string(head, envp->name->name); 3833 ccs_io_printf(head, "\"]%s=", 3834 envp->is_not ? "!" : ""); 3835 if (envp->value) { 3836 ccs_set_string(head, "\""); 3837 ccs_set_string(head, envp-> 3838 value->name); 3839 ccs_set_string(head, "\""); 3840 } else { 3841 ccs_set_string(head, "NULL"); 3842 } 3843 envp++; 3844 continue; 3845 case CCS_NUMBER_UNION: 3846 ccs_print_number_union_nospace 3847 (head, numbers_p++); 3848 break; 3849 default: 3850 ccs_set_string(head, 3851 ccs_condition_keyword[left]); 3852 break; 3853 } 3854 ccs_set_string(head, match ? "=" : "!="); 3855 switch (right) { 3856 case CCS_NAME_UNION: 3857 ccs_print_name_union_quoted 3858 (head, names_p++); 3859 break; 3860 case CCS_NUMBER_UNION: 3861 ccs_print_number_union_nospace 3862 (head, numbers_p++); 3863 break; 3864 default: 3865 ccs_set_string(head, 3866 ccs_condition_keyword[right]); 3867 break; 3868 } 3869 } 3870 } 3871 head->r.cond_step++; 3872 /* fall through */ 3873 fallthrough; 3874 case 2: 3875 if (!ccs_flush(head)) 3876 break; 3877 head->r.cond_step++; 3878 /* fall through */ 3879 fallthrough; 3880 case 3: 3881 if (cond->grant_log != CCS_GRANTLOG_AUTO) 3882 ccs_io_printf(head, " grant_log=%s", 3883 ccs_yesno(cond->grant_log == 3884 CCS_GRANTLOG_YES)); 3885 if (cond->transit && !cond->exec_transit) { 3886 const char *name = cond->transit->name; 3887 ccs_set_string(head, " auto_domain_transition=\""); 3888 ccs_set_string(head, name); 3889 ccs_set_string(head, "\""); 3890 } 3891 ccs_set_lf(head); 3892 return true; 3893 } 3894 return false; 3895 } 3896 3897 /** 3898 * ccs_set_group - Print "acl_group " header keyword and category name. 3899 * 3900 * @head: Pointer to "struct ccs_io_buffer". 3901 * @category: Category name. 3902 * 3903 * Returns nothing. 3904 */ 3905 static void ccs_set_group(struct ccs_io_buffer *head, const char *category) 3906 { 3907 if (head->type == CCS_EXCEPTION_POLICY) { 3908 ccs_print_namespace(head); 3909 ccs_io_printf(head, "acl_group %u ", head->r.acl_group_index); 3910 } 3911 ccs_set_string(head, category); 3912 } 3913 3914 /** 3915 * ccs_print_entry - Print an ACL entry. 3916 * 3917 * @head: Pointer to "struct ccs_io_buffer". 3918 * @acl: Pointer to an ACL entry. 3919 * 3920 * Returns true on success, false otherwise. 3921 */ 3922 static bool ccs_print_entry(struct ccs_io_buffer *head, 3923 const struct ccs_acl_info *acl) 3924 { 3925 const u8 acl_type = acl->type; 3926 const bool may_trigger_transition = acl->cond && acl->cond->transit; 3927 bool first = true; 3928 u8 bit; 3929 if (head->r.print_cond_part) 3930 goto print_cond_part; 3931 if (acl->is_deleted) 3932 return true; 3933 if (!ccs_flush(head)) 3934 return false; 3935 else if (acl_type == CCS_TYPE_PATH_ACL) { 3936 struct ccs_path_acl *ptr 3937 = container_of(acl, typeof(*ptr), head); 3938 for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) { 3939 if (!(acl->perm & (1 << bit))) 3940 continue; 3941 if (head->r.print_transition_related_only && 3942 bit != CCS_TYPE_EXECUTE && !may_trigger_transition) 3943 continue; 3944 if (first) { 3945 ccs_set_group(head, "file "); 3946 first = false; 3947 } else { 3948 ccs_set_slash(head); 3949 } 3950 ccs_set_string(head, ccs_path_keyword[bit]); 3951 } 3952 if (first) 3953 return true; 3954 ccs_print_name_union(head, &ptr->name); 3955 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3956 } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER || 3957 acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) { 3958 struct ccs_handler_acl *ptr 3959 = container_of(acl, typeof(*ptr), head); 3960 ccs_set_group(head, "task "); 3961 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER 3962 ? "auto_execute_handler " : 3963 "denied_execute_handler "); 3964 ccs_set_string(head, ptr->handler->name); 3965 #endif 3966 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 3967 } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL || 3968 acl_type == CCS_TYPE_MANUAL_TASK_ACL) { 3969 struct ccs_task_acl *ptr = 3970 container_of(acl, typeof(*ptr), head); 3971 ccs_set_group(head, "task "); 3972 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ? 3973 "auto_domain_transition " : 3974 "manual_domain_transition "); 3975 ccs_set_string(head, ptr->domainname->name); 3976 #endif 3977 } else if (head->r.print_transition_related_only && 3978 !may_trigger_transition) { 3979 return true; 3980 } else if (acl_type == CCS_TYPE_MKDEV_ACL) { 3981 struct ccs_mkdev_acl *ptr = 3982 container_of(acl, typeof(*ptr), head); 3983 for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) { 3984 if (!(acl->perm & (1 << bit))) 3985 continue; 3986 if (first) { 3987 ccs_set_group(head, "file "); 3988 first = false; 3989 } else { 3990 ccs_set_slash(head); 3991 } 3992 ccs_set_string(head, ccs_mac_keywords 3993 [ccs_pnnn2mac[bit]]); 3994 } 3995 if (first) 3996 return true; 3997 ccs_print_name_union(head, &ptr->name); 3998 ccs_print_number_union(head, &ptr->mode); 3999 ccs_print_number_union(head, &ptr->major); 4000 ccs_print_number_union(head, &ptr->minor); 4001 } else if (acl_type == CCS_TYPE_PATH2_ACL) { 4002 struct ccs_path2_acl *ptr = 4003 container_of(acl, typeof(*ptr), head); 4004 for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) { 4005 if (!(acl->perm & (1 << bit))) 4006 continue; 4007 if (first) { 4008 ccs_set_group(head, "file "); 4009 first = false; 4010 } else { 4011 ccs_set_slash(head); 4012 } 4013 ccs_set_string(head, ccs_mac_keywords 4014 [ccs_pp2mac[bit]]); 4015 } 4016 if (first) 4017 return true; 4018 ccs_print_name_union(head, &ptr->name1); 4019 ccs_print_name_union(head, &ptr->name2); 4020 } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) { 4021 struct ccs_path_number_acl *ptr = 4022 container_of(acl, typeof(*ptr), head); 4023 for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) { 4024 if (!(acl->perm & (1 << bit))) 4025 continue; 4026 if (first) { 4027 ccs_set_group(head, "file "); 4028 first = false; 4029 } else { 4030 ccs_set_slash(head); 4031 } 4032 ccs_set_string(head, ccs_mac_keywords 4033 [ccs_pn2mac[bit]]); 4034 } 4035 if (first) 4036 return true; 4037 ccs_print_name_union(head, &ptr->name); 4038 ccs_print_number_union(head, &ptr->number); 4039 #ifdef CONFIG_CCSECURITY_MISC 4040 } else if (acl_type == CCS_TYPE_ENV_ACL) { 4041 struct ccs_env_acl *ptr = 4042 container_of(acl, typeof(*ptr), head); 4043 ccs_set_group(head, "misc env "); 4044 ccs_set_string(head, ptr->env->name); 4045 #endif 4046 #ifdef CONFIG_CCSECURITY_CAPABILITY 4047 } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) { 4048 struct ccs_capability_acl *ptr = 4049 container_of(acl, typeof(*ptr), head); 4050 ccs_set_group(head, "capability "); 4051 ccs_set_string(head, ccs_mac_keywords 4052 [ccs_c2mac[ptr->operation]]); 4053 #endif 4054 #ifdef CONFIG_CCSECURITY_NETWORK 4055 } else if (acl_type == CCS_TYPE_INET_ACL) { 4056 struct ccs_inet_acl *ptr = 4057 container_of(acl, typeof(*ptr), head); 4058 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) { 4059 if (!(acl->perm & (1 << bit))) 4060 continue; 4061 if (first) { 4062 ccs_set_group(head, "network inet "); 4063 ccs_set_string(head, ccs_proto_keyword 4064 [ptr->protocol]); 4065 ccs_set_space(head); 4066 first = false; 4067 } else { 4068 ccs_set_slash(head); 4069 } 4070 ccs_set_string(head, ccs_socket_keyword[bit]); 4071 } 4072 if (first) 4073 return true; 4074 ccs_set_space(head); 4075 if (!ccs_print_group(head, ptr->address.group)) { 4076 char buf[128]; 4077 ccs_print_ip(buf, sizeof(buf), &ptr->address); 4078 ccs_io_printf(head, "%s", buf); 4079 } 4080 ccs_print_number_union(head, &ptr->port); 4081 } else if (acl_type == CCS_TYPE_UNIX_ACL) { 4082 struct ccs_unix_acl *ptr = 4083 container_of(acl, typeof(*ptr), head); 4084 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) { 4085 if (!(acl->perm & (1 << bit))) 4086 continue; 4087 if (first) { 4088 ccs_set_group(head, "network unix "); 4089 ccs_set_string(head, ccs_proto_keyword 4090 [ptr->protocol]); 4091 ccs_set_space(head); 4092 first = false; 4093 } else { 4094 ccs_set_slash(head); 4095 } 4096 ccs_set_string(head, ccs_socket_keyword[bit]); 4097 } 4098 if (first) 4099 return true; 4100 ccs_print_name_union(head, &ptr->name); 4101 #endif 4102 #ifdef CONFIG_CCSECURITY_IPC 4103 } else if (acl_type == CCS_TYPE_SIGNAL_ACL) { 4104 struct ccs_signal_acl *ptr = 4105 container_of(acl, typeof(*ptr), head); 4106 ccs_set_group(head, "ipc signal "); 4107 ccs_print_number_union_nospace(head, &ptr->sig); 4108 ccs_set_space(head); 4109 ccs_set_string(head, ptr->domainname->name); 4110 #endif 4111 } else if (acl_type == CCS_TYPE_MOUNT_ACL) { 4112 struct ccs_mount_acl *ptr = 4113 container_of(acl, typeof(*ptr), head); 4114 ccs_set_group(head, "file mount"); 4115 ccs_print_name_union(head, &ptr->dev_name); 4116 ccs_print_name_union(head, &ptr->dir_name); 4117 ccs_print_name_union(head, &ptr->fs_type); 4118 ccs_print_number_union(head, &ptr->flags); 4119 } 4120 if (acl->cond) { 4121 head->r.print_cond_part = true; 4122 head->r.cond_step = 0; 4123 if (!ccs_flush(head)) 4124 return false; 4125 print_cond_part: 4126 if (!ccs_print_condition(head, acl->cond)) 4127 return false; 4128 head->r.print_cond_part = false; 4129 } else { 4130 ccs_set_lf(head); 4131 } 4132 return true; 4133 } 4134 4135 /** 4136 * ccs_read_acl - Read "struct ccs_acl_info" list. 4137 * 4138 * @head: Pointer to "struct ccs_io_buffer". 4139 * @list: Pointer to "struct list_head". 4140 * 4141 * Returns true on success, false otherwise. 4142 * 4143 * Caller holds ccs_read_lock(). 4144 */ 4145 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list) 4146 { 4147 list_for_each_cookie(head->r.acl, list) { 4148 struct ccs_acl_info *ptr = 4149 list_entry(head->r.acl, typeof(*ptr), list); 4150 if (!ccs_print_entry(head, ptr)) 4151 return false; 4152 } 4153 head->r.acl = NULL; 4154 return true; 4155 } 4156 4157 /** 4158 * ccs_read_domain - Read domain policy. 4159 * 4160 * @head: Pointer to "struct ccs_io_buffer". 4161 * 4162 * Returns nothing. 4163 * 4164 * Caller holds ccs_read_lock(). 4165 */ 4166 static void ccs_read_domain(struct ccs_io_buffer *head) 4167 { 4168 if (head->r.eof) 4169 return; 4170 list_for_each_cookie(head->r.domain, &ccs_domain_list) { 4171 struct ccs_domain_info *domain = 4172 list_entry(head->r.domain, typeof(*domain), list); 4173 switch (head->r.step) { 4174 u8 i; 4175 case 0: 4176 if (domain->is_deleted && 4177 !head->r.print_this_domain_only) 4178 continue; 4179 /* Print domainname and flags. */ 4180 ccs_set_string(head, domain->domainname->name); 4181 ccs_set_lf(head); 4182 ccs_io_printf(head, "use_profile %u\n", 4183 domain->profile); 4184 for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++) 4185 if (domain->flags[i]) 4186 ccs_set_string(head, ccs_dif[i]); 4187 head->r.index = 0; 4188 head->r.step++; 4189 /* fall through */ 4190 fallthrough; 4191 case 1: 4192 while (head->r.index < CCS_MAX_ACL_GROUPS) { 4193 i = head->r.index++; 4194 if (!test_bit(i, domain->group)) 4195 continue; 4196 ccs_io_printf(head, "use_group %u\n", i); 4197 if (!ccs_flush(head)) 4198 return; 4199 } 4200 head->r.index = 0; 4201 head->r.step++; 4202 ccs_set_lf(head); 4203 /* fall through */ 4204 fallthrough; 4205 case 2: 4206 if (!ccs_read_acl(head, &domain->acl_info_list)) 4207 return; 4208 head->r.step++; 4209 if (!ccs_set_lf(head)) 4210 return; 4211 /* fall through */ 4212 fallthrough; 4213 case 3: 4214 head->r.step = 0; 4215 if (head->r.print_this_domain_only) 4216 goto done; 4217 } 4218 } 4219 done: 4220 head->r.eof = true; 4221 } 4222 4223 /** 4224 * ccs_write_pid - Specify PID to obtain domainname. 4225 * 4226 * @head: Pointer to "struct ccs_io_buffer". 4227 * 4228 * Returns 0. 4229 */ 4230 static int ccs_write_pid(struct ccs_io_buffer *head) 4231 { 4232 head->r.eof = false; 4233 return 0; 4234 } 4235 4236 /** 4237 * ccs_read_pid - Read information of a process. 4238 * 4239 * @head: Pointer to "struct ccs_io_buffer". 4240 * 4241 * Returns the domainname which the specified PID is in or 4242 * process information of the specified PID on success, 4243 * empty string otherwise. 4244 * 4245 * Caller holds ccs_read_lock(). 4246 */ 4247 static void ccs_read_pid(struct ccs_io_buffer *head) 4248 { 4249 char *buf = head->write_buf; 4250 bool task_info = false; 4251 bool global_pid = false; 4252 unsigned int pid; 4253 struct task_struct *p; 4254 struct ccs_domain_info *domain = NULL; 4255 u32 ccs_flags = 0; 4256 /* Accessing write_buf is safe because head->io_sem is held. */ 4257 if (!buf) { 4258 head->r.eof = true; 4259 return; /* Do nothing if open(O_RDONLY). */ 4260 } 4261 if (head->r.w_pos || head->r.eof) 4262 return; 4263 head->r.eof = true; 4264 if (ccs_str_starts(&buf, "info ")) 4265 task_info = true; 4266 if (ccs_str_starts(&buf, "global-pid ")) 4267 global_pid = true; 4268 pid = (unsigned int) simple_strtoul(buf, NULL, 10); 4269 ccs_tasklist_lock(); 4270 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 4271 if (global_pid) 4272 p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns); 4273 else 4274 p = ccsecurity_exports.find_task_by_vpid(pid); 4275 #else 4276 p = find_task_by_pid(pid); 4277 #endif 4278 if (p) { 4279 domain = ccs_task_domain(p); 4280 ccs_flags = ccs_task_flags(p); 4281 } 4282 ccs_tasklist_unlock(); 4283 if (!domain) 4284 return; 4285 if (!task_info) { 4286 ccs_io_printf(head, "%u %u ", pid, domain->profile); 4287 ccs_set_string(head, domain->domainname->name); 4288 } else { 4289 ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid, 4290 ccs_yesno(ccs_flags & 4291 CCS_TASK_IS_MANAGER), 4292 ccs_yesno(ccs_flags & 4293 CCS_TASK_IS_EXECUTE_HANDLER)); 4294 } 4295 } 4296 4297 /** 4298 * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list. 4299 * 4300 * @param: Pointer to "struct ccs_acl_param". 4301 * @type: Type of this group. 4302 * 4303 * Returns 0 on success, negative value otherwise. 4304 */ 4305 static int ccs_write_group(struct ccs_acl_param *param, const u8 type) 4306 { 4307 struct ccs_group *group = ccs_get_group(param, type); 4308 int error = -EINVAL; 4309 if (!group) 4310 return -ENOMEM; 4311 param->list = &group->member_list; 4312 if (type == CCS_PATH_GROUP) { 4313 struct ccs_path_group *e = ¶m->e.path_group; 4314 e->member_name = ccs_get_name(ccs_read_token(param)); 4315 if (!e->member_name) { 4316 error = -ENOMEM; 4317 goto out; 4318 } 4319 error = ccs_update_policy(sizeof(*e), param); 4320 ccs_put_name(e->member_name); 4321 } else if (type == CCS_NUMBER_GROUP) { 4322 struct ccs_number_group *e = ¶m->e.number_group; 4323 if (param->data[0] == '@' || 4324 !ccs_parse_number_union(param, &e->number)) 4325 goto out; 4326 error = ccs_update_policy(sizeof(*e), param); 4327 #ifdef CONFIG_CCSECURITY_NETWORK 4328 } else { 4329 struct ccs_address_group *e = ¶m->e.address_group; 4330 if (param->data[0] == '@' || 4331 !ccs_parse_ipaddr_union(param, &e->address)) 4332 goto out; 4333 error = ccs_update_policy(sizeof(*e), param); 4334 #endif 4335 } 4336 out: 4337 ccs_put_group(group); 4338 return error; 4339 } 4340 4341 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4342 /** 4343 * ccs_lport_reserved - Check whether local port is reserved or not. 4344 * 4345 * @port: Port number. 4346 * 4347 * Returns true if local port is reserved, false otherwise. 4348 */ 4349 static bool __ccs_lport_reserved(const u16 port) 4350 { 4351 return ccs_reserved_port_map[port >> 3] & (1 << (port & 7)) 4352 ? true : false; 4353 } 4354 4355 /** 4356 * ccs_write_reserved_port - Update "struct ccs_reserved" list. 4357 * 4358 * @param: Pointer to "struct ccs_acl_param". 4359 * 4360 * Returns 0 on success, negative value otherwise. 4361 * 4362 * Caller holds ccs_read_lock(). 4363 */ 4364 static int ccs_write_reserved_port(struct ccs_acl_param *param) 4365 { 4366 struct ccs_reserved *e = ¶m->e.reserved; 4367 struct ccs_policy_namespace *ns = param->ns; 4368 int error; 4369 u8 *tmp; 4370 if (param->data[0] == '@' || 4371 !ccs_parse_number_union(param, &e->port) || 4372 e->port.values[1] > 65535 || param->data[0]) 4373 return -EINVAL; 4374 param->list = &ns->policy_list[CCS_ID_RESERVEDPORT]; 4375 error = ccs_update_policy(sizeof(*e), param); 4376 if (error) 4377 return error; 4378 tmp = kzalloc(sizeof(ccs_reserved_port_map), CCS_GFP_FLAGS); 4379 if (!tmp) 4380 return -ENOMEM; 4381 list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list, 4382 &ccs_ss) { 4383 struct ccs_reserved *ptr; 4384 struct list_head *list = &ns->policy_list[CCS_ID_RESERVEDPORT]; 4385 list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) { 4386 unsigned int port; 4387 if (ptr->head.is_deleted) 4388 continue; 4389 for (port = ptr->port.values[0]; 4390 port <= ptr->port.values[1]; port++) 4391 tmp[port >> 3] |= 1 << (port & 7); 4392 } 4393 } 4394 memmove(ccs_reserved_port_map, tmp, sizeof(ccs_reserved_port_map)); 4395 kfree(tmp); 4396 /* 4397 * Since this feature is no-op by default, we don't need to register 4398 * this callback hook unless the first entry is added. 4399 */ 4400 ccsecurity_ops.lport_reserved = __ccs_lport_reserved; 4401 return 0; 4402 } 4403 #endif 4404 4405 /** 4406 * ccs_write_aggregator - Write "struct ccs_aggregator" list. 4407 * 4408 * @param: Pointer to "struct ccs_acl_param". 4409 * 4410 * Returns 0 on success, negative value otherwise. 4411 */ 4412 static int ccs_write_aggregator(struct ccs_acl_param *param) 4413 { 4414 struct ccs_aggregator *e = ¶m->e.aggregator; 4415 int error = param->is_delete ? -ENOENT : -ENOMEM; 4416 const char *original_name = ccs_read_token(param); 4417 const char *aggregated_name = ccs_read_token(param); 4418 if (!ccs_correct_word(original_name) || 4419 !ccs_correct_path(aggregated_name)) 4420 return -EINVAL; 4421 e->original_name = ccs_get_name(original_name); 4422 e->aggregated_name = ccs_get_name(aggregated_name); 4423 if (!e->original_name || !e->aggregated_name || 4424 e->aggregated_name->is_patterned) /* No patterns allowed. */ 4425 goto out; 4426 param->list = ¶m->ns->policy_list[CCS_ID_AGGREGATOR]; 4427 error = ccs_update_policy(sizeof(*e), param); 4428 out: 4429 ccs_put_name(e->original_name); 4430 ccs_put_name(e->aggregated_name); 4431 return error; 4432 } 4433 4434 /** 4435 * ccs_write_transition_control - Write "struct ccs_transition_control" list. 4436 * 4437 * @param: Pointer to "struct ccs_acl_param". 4438 * @type: Type of this entry. 4439 * 4440 * Returns 0 on success, negative value otherwise. 4441 */ 4442 static int ccs_write_transition_control(struct ccs_acl_param *param, 4443 const u8 type) 4444 { 4445 struct ccs_transition_control *e = ¶m->e.transition_control; 4446 int error = param->is_delete ? -ENOENT : -ENOMEM; 4447 char *program = param->data; 4448 char *domainname = strstr(program, " from "); 4449 e->type = type; 4450 if (domainname) { 4451 *domainname = '\0'; 4452 domainname += 6; 4453 } else if (type == CCS_TRANSITION_CONTROL_NO_KEEP || 4454 type == CCS_TRANSITION_CONTROL_KEEP) { 4455 domainname = program; 4456 program = NULL; 4457 } 4458 if (program && strcmp(program, "any")) { 4459 if (!ccs_correct_path(program)) 4460 return -EINVAL; 4461 e->program = ccs_get_name(program); 4462 if (!e->program) 4463 goto out; 4464 } 4465 if (domainname && strcmp(domainname, "any")) { 4466 if (!ccs_correct_domain(domainname)) { 4467 if (!ccs_correct_path(domainname)) 4468 goto out; 4469 e->is_last_name = true; 4470 } 4471 e->domainname = ccs_get_name(domainname); 4472 if (!e->domainname) 4473 goto out; 4474 } 4475 param->list = ¶m->ns->policy_list[CCS_ID_TRANSITION_CONTROL]; 4476 error = ccs_update_policy(sizeof(*e), param); 4477 out: 4478 ccs_put_name(e->domainname); 4479 ccs_put_name(e->program); 4480 return error; 4481 } 4482 4483 /** 4484 * ccs_write_exception - Write exception policy. 4485 * 4486 * @head: Pointer to "struct ccs_io_buffer". 4487 * 4488 * Returns 0 on success, negative value otherwise. 4489 */ 4490 static int ccs_write_exception(struct ccs_io_buffer *head) 4491 { 4492 const bool is_delete = head->w.is_delete; 4493 struct ccs_acl_param param = { 4494 .ns = head->w.ns, 4495 .is_delete = is_delete, 4496 .data = head->write_buf, 4497 }; 4498 u8 i; 4499 /* Forced zero clear for using memcmp() at ccs_update_policy(). */ 4500 memset(¶m.e, 0, sizeof(param.e)); 4501 if (ccs_str_starts(¶m.data, "aggregator ")) 4502 return ccs_write_aggregator(¶m); 4503 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4504 if (ccs_str_starts(¶m.data, "deny_autobind ")) 4505 return ccs_write_reserved_port(¶m); 4506 #endif 4507 for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) 4508 if (ccs_str_starts(¶m.data, ccs_transition_type[i])) 4509 return ccs_write_transition_control(¶m, i); 4510 for (i = 0; i < CCS_MAX_GROUP; i++) 4511 if (ccs_str_starts(¶m.data, ccs_group_name[i])) 4512 return ccs_write_group(¶m, i); 4513 if (ccs_str_starts(¶m.data, "acl_group ")) { 4514 unsigned int group; 4515 char *data; 4516 group = simple_strtoul(param.data, &data, 10); 4517 if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ') 4518 return ccs_write_acl(head->w.ns, 4519 &head->w.ns->acl_group[group], 4520 data, is_delete); 4521 } 4522 return -EINVAL; 4523 } 4524 4525 /** 4526 * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list. 4527 * 4528 * @head: Pointer to "struct ccs_io_buffer". 4529 * @idx: Index number. 4530 * 4531 * Returns true on success, false otherwise. 4532 * 4533 * Caller holds ccs_read_lock(). 4534 */ 4535 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx) 4536 { 4537 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4538 namespace_list); 4539 struct list_head *list = &ns->group_list[idx]; 4540 list_for_each_cookie(head->r.group, list) { 4541 struct ccs_group *group = 4542 list_entry(head->r.group, typeof(*group), head.list); 4543 list_for_each_cookie(head->r.acl, &group->member_list) { 4544 struct ccs_acl_head *ptr = 4545 list_entry(head->r.acl, typeof(*ptr), list); 4546 if (ptr->is_deleted) 4547 continue; 4548 if (!ccs_flush(head)) 4549 return false; 4550 ccs_print_namespace(head); 4551 ccs_set_string(head, ccs_group_name[idx]); 4552 ccs_set_string(head, group->group_name->name); 4553 if (idx == CCS_PATH_GROUP) { 4554 ccs_set_space(head); 4555 ccs_set_string(head, container_of 4556 (ptr, struct ccs_path_group, 4557 head)->member_name->name); 4558 } else if (idx == CCS_NUMBER_GROUP) { 4559 ccs_print_number_union(head, &container_of 4560 (ptr, struct ccs_number_group, 4561 head)->number); 4562 #ifdef CONFIG_CCSECURITY_NETWORK 4563 } else if (idx == CCS_ADDRESS_GROUP) { 4564 char buffer[128]; 4565 struct ccs_address_group *member = 4566 container_of(ptr, typeof(*member), 4567 head); 4568 ccs_print_ip(buffer, sizeof(buffer), 4569 &member->address); 4570 ccs_io_printf(head, " %s", buffer); 4571 #endif 4572 } 4573 ccs_set_lf(head); 4574 } 4575 head->r.acl = NULL; 4576 } 4577 head->r.group = NULL; 4578 return true; 4579 } 4580 4581 /** 4582 * ccs_read_policy - Read "struct ccs_..._entry" list. 4583 * 4584 * @head: Pointer to "struct ccs_io_buffer". 4585 * @idx: Index number. 4586 * 4587 * Returns true on success, false otherwise. 4588 * 4589 * Caller holds ccs_read_lock(). 4590 */ 4591 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx) 4592 { 4593 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4594 namespace_list); 4595 struct list_head *list = &ns->policy_list[idx]; 4596 list_for_each_cookie(head->r.acl, list) { 4597 struct ccs_acl_head *acl = 4598 container_of(head->r.acl, typeof(*acl), list); 4599 if (acl->is_deleted) 4600 continue; 4601 if (head->r.print_transition_related_only && 4602 idx != CCS_ID_TRANSITION_CONTROL) 4603 continue; 4604 if (!ccs_flush(head)) 4605 return false; 4606 switch (idx) { 4607 case CCS_ID_TRANSITION_CONTROL: 4608 { 4609 struct ccs_transition_control *ptr = 4610 container_of(acl, typeof(*ptr), head); 4611 ccs_print_namespace(head); 4612 ccs_set_string(head, 4613 ccs_transition_type[ptr->type]); 4614 ccs_set_string(head, ptr->program ? 4615 ptr->program->name : "any"); 4616 ccs_set_string(head, " from "); 4617 ccs_set_string(head, ptr->domainname ? 4618 ptr->domainname->name : "any"); 4619 } 4620 break; 4621 case CCS_ID_AGGREGATOR: 4622 { 4623 struct ccs_aggregator *ptr = 4624 container_of(acl, typeof(*ptr), head); 4625 ccs_print_namespace(head); 4626 ccs_set_string(head, "aggregator "); 4627 ccs_set_string(head, ptr->original_name->name); 4628 ccs_set_space(head); 4629 ccs_set_string(head, 4630 ptr->aggregated_name->name); 4631 } 4632 break; 4633 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4634 case CCS_ID_RESERVEDPORT: 4635 { 4636 struct ccs_reserved *ptr = 4637 container_of(acl, typeof(*ptr), head); 4638 ccs_print_namespace(head); 4639 ccs_set_string(head, "deny_autobind "); 4640 ccs_print_number_union_nospace(head, 4641 &ptr->port); 4642 } 4643 break; 4644 #endif 4645 default: 4646 continue; 4647 } 4648 ccs_set_lf(head); 4649 } 4650 head->r.acl = NULL; 4651 return true; 4652 } 4653 4654 /** 4655 * ccs_read_exception - Read exception policy. 4656 * 4657 * @head: Pointer to "struct ccs_io_buffer". 4658 * 4659 * Returns nothing. 4660 * 4661 * Caller holds ccs_read_lock(). 4662 */ 4663 static void ccs_read_exception(struct ccs_io_buffer *head) 4664 { 4665 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4666 namespace_list); 4667 if (head->r.eof) 4668 return; 4669 while (head->r.step < CCS_MAX_POLICY && 4670 ccs_read_policy(head, head->r.step)) 4671 head->r.step++; 4672 if (head->r.step < CCS_MAX_POLICY) 4673 return; 4674 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP && 4675 ccs_read_group(head, head->r.step - CCS_MAX_POLICY)) 4676 head->r.step++; 4677 if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP) 4678 return; 4679 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP 4680 + CCS_MAX_ACL_GROUPS) { 4681 head->r.acl_group_index = 4682 head->r.step - CCS_MAX_POLICY - CCS_MAX_GROUP; 4683 if (!ccs_read_acl(head, &ns->acl_group 4684 [head->r.acl_group_index])) 4685 return; 4686 head->r.step++; 4687 } 4688 head->r.eof = true; 4689 } 4690 4691 /** 4692 * ccs_truncate - Truncate a line. 4693 * 4694 * @str: String to truncate. 4695 * 4696 * Returns length of truncated @str. 4697 */ 4698 static int ccs_truncate(char *str) 4699 { 4700 char *start = str; 4701 while (*(unsigned char *) str > (unsigned char) ' ') 4702 str++; 4703 *str = '\0'; 4704 return strlen(start) + 1; 4705 } 4706 4707 /** 4708 * ccs_add_entry - Add an ACL to current thread's domain. Used by learning mode. 4709 * 4710 * @header: Lines containing ACL. 4711 * 4712 * Returns nothing. 4713 */ 4714 static void ccs_add_entry(char *header) 4715 { 4716 char *buffer; 4717 char *realpath = NULL; 4718 char *argv0 = NULL; 4719 char *symlink = NULL; 4720 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4721 char *handler; 4722 #endif 4723 char *cp = strchr(header, '\n'); 4724 int len; 4725 if (!cp) 4726 return; 4727 cp = strchr(cp + 1, '\n'); 4728 if (!cp) 4729 return; 4730 *cp++ = '\0'; 4731 len = strlen(cp) + 1; 4732 /* strstr() will return NULL if ordering is wrong. */ 4733 if (*cp == 'f') { 4734 argv0 = strstr(header, " argv[]={ \""); 4735 if (argv0) { 4736 argv0 += 10; 4737 len += ccs_truncate(argv0) + 14; 4738 } 4739 realpath = strstr(header, " exec={ realpath=\""); 4740 if (realpath) { 4741 realpath += 8; 4742 len += ccs_truncate(realpath) + 6; 4743 } 4744 symlink = strstr(header, " symlink.target=\""); 4745 if (symlink) 4746 len += ccs_truncate(symlink + 1) + 1; 4747 } 4748 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4749 handler = strstr(header, "type=execute_handler"); 4750 if (handler) 4751 len += ccs_truncate(handler) + 6; 4752 #endif 4753 buffer = kmalloc(len, CCS_GFP_FLAGS); 4754 if (!buffer) 4755 return; 4756 snprintf(buffer, len - 1, "%s", cp); 4757 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4758 if (handler) 4759 ccs_addprintf(buffer, len, " task.%s", handler); 4760 #endif 4761 if (realpath) 4762 ccs_addprintf(buffer, len, " exec.%s", realpath); 4763 if (argv0) 4764 ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0); 4765 if (symlink) 4766 ccs_addprintf(buffer, len, "%s", symlink); 4767 ccs_normalize_line(buffer); 4768 { 4769 struct ccs_domain_info *domain = ccs_current_domain(); 4770 if (!ccs_write_acl(domain->ns, &domain->acl_info_list, 4771 buffer, false)) 4772 ccs_update_stat(CCS_STAT_POLICY_UPDATES); 4773 } 4774 kfree(buffer); 4775 } 4776 4777 /** 4778 * ccs_domain_quota_ok - Check for domain's quota. 4779 * 4780 * @r: Pointer to "struct ccs_request_info". 4781 * 4782 * Returns true if the domain is not exceeded quota, false otherwise. 4783 * 4784 * Caller holds ccs_read_lock(). 4785 */ 4786 static bool ccs_domain_quota_ok(struct ccs_request_info *r) 4787 { 4788 unsigned int count = 0; 4789 struct ccs_domain_info * const domain = ccs_current_domain(); 4790 struct ccs_acl_info *ptr; 4791 if (r->mode != CCS_CONFIG_LEARNING) 4792 return false; 4793 if (!domain) 4794 return true; 4795 if (domain->flags[CCS_DIF_QUOTA_WARNED]) 4796 return false; 4797 list_for_each_entry_srcu(ptr, &domain->acl_info_list, list, &ccs_ss) { 4798 u16 perm; 4799 if (ptr->is_deleted) 4800 continue; 4801 switch (ptr->type) { 4802 case CCS_TYPE_PATH_ACL: 4803 case CCS_TYPE_PATH2_ACL: 4804 case CCS_TYPE_PATH_NUMBER_ACL: 4805 case CCS_TYPE_MKDEV_ACL: 4806 #ifdef CONFIG_CCSECURITY_NETWORK 4807 case CCS_TYPE_INET_ACL: 4808 case CCS_TYPE_UNIX_ACL: 4809 #endif 4810 perm = ptr->perm; 4811 break; 4812 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4813 case CCS_TYPE_AUTO_EXECUTE_HANDLER: 4814 case CCS_TYPE_DENIED_EXECUTE_HANDLER: 4815 #endif 4816 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 4817 case CCS_TYPE_AUTO_TASK_ACL: 4818 case CCS_TYPE_MANUAL_TASK_ACL: 4819 #endif 4820 perm = 0; 4821 break; 4822 default: 4823 perm = 1; 4824 } 4825 count += hweight16(perm); 4826 } 4827 if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY]) 4828 return true; 4829 domain->flags[CCS_DIF_QUOTA_WARNED] = true; 4830 /* r->granted = false; */ 4831 ccs_write_log(r, "%s", ccs_dif[CCS_DIF_QUOTA_WARNED]); 4832 printk(KERN_WARNING "WARNING: Domain '%s' has too many ACLs to hold. " 4833 "Stopped learning mode.\n", domain->domainname->name); 4834 return false; 4835 } 4836 4837 /** 4838 * ccs_supervisor - Ask for the supervisor's decision. 4839 * 4840 * @r: Pointer to "struct ccs_request_info". 4841 * @fmt: The printf()'s format string, followed by parameters. 4842 * 4843 * Returns 0 if the supervisor decided to permit the access request which 4844 * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor 4845 * decided to retry the access request which violated the policy in enforcing 4846 * mode, 0 if it is not in enforcing mode, -EPERM otherwise. 4847 */ 4848 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...) 4849 { 4850 va_list args; 4851 int error; 4852 int len; 4853 static unsigned int ccs_serial; 4854 struct ccs_query entry = { }; 4855 bool quota_exceeded = false; 4856 va_start(args, fmt); 4857 len = vsnprintf((char *) &len, 1, fmt, args) + 1; 4858 va_end(args); 4859 /* Write /proc/ccs/audit. */ 4860 va_start(args, fmt); 4861 ccs_write_log2(r, len, fmt, args); 4862 va_end(args); 4863 /* Nothing more to do if granted. */ 4864 if (r->granted) 4865 return 0; 4866 if (r->mode) 4867 ccs_update_stat(r->mode); 4868 switch (r->mode) { 4869 int i; 4870 struct ccs_profile *p; 4871 case CCS_CONFIG_ENFORCING: 4872 error = -EPERM; 4873 if (atomic_read(&ccs_query_observers)) 4874 break; 4875 if (r->dont_sleep_on_enforce_error) 4876 goto out; 4877 p = ccs_profile(r->profile); 4878 /* Check enforcing_penalty parameter. */ 4879 for (i = 0; i < p->pref[CCS_PREF_ENFORCING_PENALTY]; i++) { 4880 set_current_state(TASK_INTERRUPTIBLE); 4881 schedule_timeout(HZ / 10); 4882 } 4883 goto out; 4884 case CCS_CONFIG_LEARNING: 4885 error = 0; 4886 /* Check max_learning_entry parameter. */ 4887 if (ccs_domain_quota_ok(r)) 4888 break; 4889 /* fall through */ 4890 fallthrough; 4891 default: 4892 return 0; 4893 } 4894 /* Get message. */ 4895 va_start(args, fmt); 4896 entry.query = ccs_init_log(r, len, fmt, args); 4897 va_end(args); 4898 if (!entry.query) 4899 goto out; 4900 entry.query_len = strlen(entry.query) + 1; 4901 if (!error) { 4902 ccs_add_entry(entry.query); 4903 goto out; 4904 } 4905 len = ccs_round2(entry.query_len); 4906 entry.domain = ccs_current_domain(); 4907 spin_lock(&ccs_query_list_lock); 4908 if (ccs_memory_quota[CCS_MEMORY_QUERY] && 4909 ccs_memory_used[CCS_MEMORY_QUERY] + len 4910 >= ccs_memory_quota[CCS_MEMORY_QUERY]) { 4911 quota_exceeded = true; 4912 } else { 4913 entry.serial = ccs_serial++; 4914 entry.retry = r->retry; 4915 ccs_memory_used[CCS_MEMORY_QUERY] += len; 4916 list_add_tail(&entry.list, &ccs_query_list); 4917 } 4918 spin_unlock(&ccs_query_list_lock); 4919 if (quota_exceeded) 4920 goto out; 4921 /* Give 10 seconds for supervisor's opinion. */ 4922 while (entry.timer < 10) { 4923 wake_up_all(&ccs_query_wait); 4924 if (wait_event_interruptible_timeout 4925 (ccs_answer_wait, entry.answer || 4926 !atomic_read(&ccs_query_observers), HZ)) 4927 break; 4928 else 4929 entry.timer++; 4930 } 4931 spin_lock(&ccs_query_list_lock); 4932 list_del(&entry.list); 4933 ccs_memory_used[CCS_MEMORY_QUERY] -= len; 4934 spin_unlock(&ccs_query_list_lock); 4935 switch (entry.answer) { 4936 case 3: /* Asked to retry by administrator. */ 4937 error = CCS_RETRY_REQUEST; 4938 r->retry++; 4939 break; 4940 case 1: 4941 /* Granted by administrator. */ 4942 error = 0; 4943 break; 4944 default: 4945 /* Timed out or rejected by administrator. */ 4946 break; 4947 } 4948 out: 4949 kfree(entry.query); 4950 return error; 4951 } 4952 4953 /** 4954 * ccs_audit_log - Audit permission check log. 4955 * 4956 * @r: Pointer to "struct ccs_request_info". 4957 * 4958 * Returns return value of ccs_supervisor(). 4959 */ 4960 int ccs_audit_log(struct ccs_request_info *r) 4961 { 4962 switch (r->param_type) { 4963 u8 type; 4964 char buf[48]; 4965 #ifdef CONFIG_CCSECURITY_NETWORK 4966 const u32 *address; 4967 #endif 4968 case CCS_TYPE_PATH_ACL: 4969 return ccs_supervisor(r, "file %s %s\n", ccs_path_keyword 4970 [r->param.path.operation], 4971 r->param.path.filename->name); 4972 case CCS_TYPE_PATH2_ACL: 4973 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords 4974 [ccs_pp2mac[r->param.path2.operation]], 4975 r->param.path2.filename1->name, 4976 r->param.path2.filename2->name); 4977 case CCS_TYPE_PATH_NUMBER_ACL: 4978 type = r->param.path_number.operation; 4979 switch (type) { 4980 case CCS_TYPE_CREATE: 4981 case CCS_TYPE_MKDIR: 4982 case CCS_TYPE_MKFIFO: 4983 case CCS_TYPE_MKSOCK: 4984 case CCS_TYPE_CHMOD: 4985 snprintf(buf, sizeof(buf), "0%lo", 4986 r->param.path_number.number); 4987 break; 4988 case CCS_TYPE_IOCTL: 4989 snprintf(buf, sizeof(buf), "0x%lX", 4990 r->param.path_number.number); 4991 break; 4992 default: 4993 snprintf(buf, sizeof(buf), "%lu", 4994 r->param.path_number.number); 4995 break; 4996 } 4997 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords 4998 [ccs_pn2mac[type]], 4999 r->param.path_number.filename->name, 5000 buf); 5001 case CCS_TYPE_MKDEV_ACL: 5002 return ccs_supervisor(r, "file %s %s 0%o %u %u\n", 5003 ccs_mac_keywords 5004 [ccs_pnnn2mac[r->param.mkdev.operation]], 5005 r->param.mkdev.filename->name, 5006 r->param.mkdev.mode, 5007 r->param.mkdev.major, 5008 r->param.mkdev.minor); 5009 case CCS_TYPE_MOUNT_ACL: 5010 return ccs_supervisor(r, "file mount %s %s %s 0x%lX\n", 5011 r->param.mount.dev->name, 5012 r->param.mount.dir->name, 5013 r->param.mount.type->name, 5014 r->param.mount.flags); 5015 #ifdef CONFIG_CCSECURITY_MISC 5016 case CCS_TYPE_ENV_ACL: 5017 return ccs_supervisor(r, "misc env %s\n", 5018 r->param.environ.name->name); 5019 #endif 5020 #ifdef CONFIG_CCSECURITY_CAPABILITY 5021 case CCS_TYPE_CAPABILITY_ACL: 5022 return ccs_supervisor(r, "capability %s\n", ccs_mac_keywords 5023 [ccs_c2mac[r->param.capability. 5024 operation]]); 5025 #endif 5026 #ifdef CONFIG_CCSECURITY_NETWORK 5027 case CCS_TYPE_INET_ACL: 5028 address = r->param.inet_network.address; 5029 if (r->param.inet_network.is_ipv6) 5030 ccs_print_ipv6(buf, sizeof(buf), 5031 (const struct in6_addr *) address); 5032 else 5033 ccs_print_ipv4(buf, sizeof(buf), address); 5034 return ccs_supervisor(r, "network inet %s %s %s %u\n", 5035 ccs_proto_keyword[r->param.inet_network. 5036 protocol], 5037 ccs_socket_keyword[r->param.inet_network. 5038 operation], 5039 buf, r->param.inet_network.port); 5040 case CCS_TYPE_UNIX_ACL: 5041 return ccs_supervisor(r, "network unix %s %s %s\n", 5042 ccs_proto_keyword[r->param. 5043 unix_network.protocol], 5044 ccs_socket_keyword[r->param.unix_network. 5045 operation], 5046 r->param.unix_network.address->name); 5047 #endif 5048 #ifdef CONFIG_CCSECURITY_IPC 5049 case CCS_TYPE_SIGNAL_ACL: 5050 return ccs_supervisor(r, "ipc signal %d %s\n", 5051 r->param.signal.sig, 5052 r->param.signal.dest_pattern); 5053 #endif 5054 } 5055 return 0; 5056 } 5057 5058 /** 5059 * ccs_find_domain_by_qid - Get domain by query id. 5060 * 5061 * @serial: Query ID assigned by ccs_supervisor(). 5062 * 5063 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise. 5064 */ 5065 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial) 5066 { 5067 struct ccs_query *ptr; 5068 struct ccs_domain_info *domain = NULL; 5069 spin_lock(&ccs_query_list_lock); 5070 list_for_each_entry(ptr, &ccs_query_list, list) { 5071 if (ptr->serial != serial) 5072 continue; 5073 domain = ptr->domain; 5074 break; 5075 } 5076 spin_unlock(&ccs_query_list_lock); 5077 return domain; 5078 } 5079 5080 /** 5081 * ccs_read_query - Read access requests which violated policy in enforcing mode. 5082 * 5083 * @head: Pointer to "struct ccs_io_buffer". 5084 * 5085 * Returns nothing. 5086 */ 5087 static void ccs_read_query(struct ccs_io_buffer *head) 5088 { 5089 struct list_head *tmp; 5090 unsigned int pos = 0; 5091 size_t len = 0; 5092 char *buf; 5093 if (head->r.w_pos) 5094 return; 5095 kfree(head->read_buf); 5096 head->read_buf = NULL; 5097 spin_lock(&ccs_query_list_lock); 5098 list_for_each(tmp, &ccs_query_list) { 5099 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5100 if (pos++ != head->r.query_index) 5101 continue; 5102 len = ptr->query_len; 5103 break; 5104 } 5105 spin_unlock(&ccs_query_list_lock); 5106 if (!len) { 5107 head->r.query_index = 0; 5108 return; 5109 } 5110 buf = kzalloc(len + 32, CCS_GFP_FLAGS); 5111 if (!buf) 5112 return; 5113 pos = 0; 5114 spin_lock(&ccs_query_list_lock); 5115 list_for_each(tmp, &ccs_query_list) { 5116 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5117 if (pos++ != head->r.query_index) 5118 continue; 5119 /* 5120 * Some query can be skipped because ccs_query_list 5121 * can change, but I don't care. 5122 */ 5123 if (len == ptr->query_len) 5124 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial, 5125 ptr->retry, ptr->query); 5126 break; 5127 } 5128 spin_unlock(&ccs_query_list_lock); 5129 if (buf[0]) { 5130 head->read_buf = buf; 5131 head->r.w[head->r.w_pos++] = buf; 5132 head->r.query_index++; 5133 } else { 5134 kfree(buf); 5135 } 5136 } 5137 5138 /** 5139 * ccs_write_answer - Write the supervisor's decision. 5140 * 5141 * @head: Pointer to "struct ccs_io_buffer". 5142 * 5143 * Returns 0 on success, -EINVAL otherwise. 5144 */ 5145 static int ccs_write_answer(struct ccs_io_buffer *head) 5146 { 5147 char *data = head->write_buf; 5148 struct list_head *tmp; 5149 unsigned int serial; 5150 unsigned int answer; 5151 spin_lock(&ccs_query_list_lock); 5152 list_for_each(tmp, &ccs_query_list) { 5153 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5154 ptr->timer = 0; 5155 } 5156 spin_unlock(&ccs_query_list_lock); 5157 if (sscanf(data, "A%u=%u", &serial, &answer) != 2) 5158 return -EINVAL; 5159 spin_lock(&ccs_query_list_lock); 5160 list_for_each(tmp, &ccs_query_list) { 5161 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5162 if (ptr->serial != serial) 5163 continue; 5164 ptr->answer = (u8) answer; 5165 /* Remove from ccs_query_list. */ 5166 if (ptr->answer) { 5167 list_del(&ptr->list); 5168 INIT_LIST_HEAD(&ptr->list); 5169 } 5170 break; 5171 } 5172 spin_unlock(&ccs_query_list_lock); 5173 wake_up_all(&ccs_answer_wait); 5174 return 0; 5175 } 5176 5177 /** 5178 * ccs_read_version - Get version. 5179 * 5180 * @head: Pointer to "struct ccs_io_buffer". 5181 * 5182 * Returns nothing. 5183 */ 5184 static void ccs_read_version(struct ccs_io_buffer *head) 5185 { 5186 if (head->r.eof) 5187 return; 5188 ccs_set_string(head, "1.8.11"); 5189 head->r.eof = true; 5190 } 5191 5192 /** 5193 * ccs_update_stat - Update statistic counters. 5194 * 5195 * @index: Index for policy type. 5196 * 5197 * Returns nothing. 5198 */ 5199 static void ccs_update_stat(const u8 index) 5200 { 5201 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 5202 struct timeval tv; 5203 #endif 5204 5205 atomic_inc(&ccs_stat_updated[index]); 5206 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 5207 do_gettimeofday(&tv); 5208 ccs_stat_modified[index] = tv.tv_sec; 5209 #elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) 5210 ccs_stat_modified[index] = get_seconds(); 5211 #else 5212 ccs_stat_modified[index] = ktime_get_real_seconds(); 5213 #endif 5214 } 5215 5216 /** 5217 * ccs_read_stat - Read statistic data. 5218 * 5219 * @head: Pointer to "struct ccs_io_buffer". 5220 * 5221 * Returns nothing. 5222 */ 5223 static void ccs_read_stat(struct ccs_io_buffer *head) 5224 { 5225 u8 i; 5226 unsigned int total = 0; 5227 if (head->r.eof) 5228 return; 5229 for (i = 0; i < CCS_MAX_POLICY_STAT; i++) { 5230 ccs_io_printf(head, "Policy %-30s %10u", ccs_policy_headers[i], 5231 atomic_read(&ccs_stat_updated[i])); 5232 if (ccs_stat_modified[i]) { 5233 struct ccs_time stamp; 5234 ccs_convert_time(ccs_stat_modified[i], &stamp); 5235 ccs_io_printf(head, " (Last: %04u/%02u/%02u " 5236 "%02u:%02u:%02u)", 5237 stamp.year, stamp.month, stamp.day, 5238 stamp.hour, stamp.min, stamp.sec); 5239 } 5240 ccs_set_lf(head); 5241 } 5242 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) { 5243 unsigned int used = ccs_memory_used[i]; 5244 total += used; 5245 ccs_io_printf(head, "Memory used by %-22s %10u", 5246 ccs_memory_headers[i], used); 5247 used = ccs_memory_quota[i]; 5248 if (used) 5249 ccs_io_printf(head, " (Quota: %10u)", used); 5250 ccs_set_lf(head); 5251 } 5252 ccs_io_printf(head, "Total memory used: %10u\n", 5253 total); 5254 head->r.eof = true; 5255 } 5256 5257 /** 5258 * ccs_write_stat - Set memory quota. 5259 * 5260 * @head: Pointer to "struct ccs_io_buffer". 5261 * 5262 * Returns 0. 5263 */ 5264 static int ccs_write_stat(struct ccs_io_buffer *head) 5265 { 5266 char *data = head->write_buf; 5267 u8 i; 5268 if (ccs_str_starts(&data, "Memory used by ")) 5269 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) 5270 if (ccs_str_starts(&data, ccs_memory_headers[i])) { 5271 if (*data == ' ') 5272 data++; 5273 ccs_memory_quota[i] = 5274 simple_strtoul(data, NULL, 10); 5275 } 5276 return 0; 5277 } 5278 5279 /** 5280 * ccs_print_bprm - Print "struct linux_binprm" for auditing. 5281 * 5282 * @bprm: Pointer to "struct linux_binprm". 5283 * @dump: Pointer to "struct ccs_page_dump". 5284 * 5285 * Returns the contents of @bprm on success, NULL otherwise. 5286 * 5287 * This function uses kzalloc(), so caller must kfree() if this function 5288 * didn't return NULL. 5289 */ 5290 static char *ccs_print_bprm(struct linux_binprm *bprm, 5291 struct ccs_page_dump *dump) 5292 { 5293 static const int ccs_buffer_len = 4096 * 2; 5294 char *buffer = kzalloc(ccs_buffer_len, CCS_GFP_FLAGS); 5295 char *cp; 5296 char *last_start; 5297 int len; 5298 unsigned long pos = bprm->p; 5299 int offset = pos % PAGE_SIZE; 5300 int argv_count = bprm->argc; 5301 int envp_count = bprm->envc; 5302 bool truncated = false; 5303 if (!buffer) 5304 return NULL; 5305 len = snprintf(buffer, ccs_buffer_len - 1, "argv[]={ "); 5306 cp = buffer + len; 5307 if (!argv_count) { 5308 memmove(cp, "} envp[]={ ", 11); 5309 cp += 11; 5310 } 5311 last_start = cp; 5312 while (argv_count || envp_count) { 5313 if (!ccs_dump_page(bprm, pos, dump)) 5314 goto out; 5315 pos += PAGE_SIZE - offset; 5316 /* Read. */ 5317 while (offset < PAGE_SIZE) { 5318 const char *kaddr = dump->data; 5319 const unsigned char c = kaddr[offset++]; 5320 if (cp == last_start) 5321 *cp++ = '"'; 5322 if (cp >= buffer + ccs_buffer_len - 32) { 5323 /* Reserve some room for "..." string. */ 5324 truncated = true; 5325 } else if (c == '\\') { 5326 *cp++ = '\\'; 5327 *cp++ = '\\'; 5328 } else if (c > ' ' && c < 127) { 5329 *cp++ = c; 5330 } else if (!c) { 5331 *cp++ = '"'; 5332 *cp++ = ' '; 5333 last_start = cp; 5334 } else { 5335 *cp++ = '\\'; 5336 *cp++ = (c >> 6) + ''; 5337 *cp++ = ((c >> 3) & 7) + ''; 5338 *cp++ = (c & 7) + ''; 5339 } 5340 if (c) 5341 continue; 5342 if (argv_count) { 5343 if (--argv_count == 0) { 5344 if (truncated) { 5345 cp = last_start; 5346 memmove(cp, "... ", 4); 5347 cp += 4; 5348 } 5349 memmove(cp, "} envp[]={ ", 11); 5350 cp += 11; 5351 last_start = cp; 5352 truncated = false; 5353 } 5354 } else if (envp_count) { 5355 if (--envp_count == 0) { 5356 if (truncated) { 5357 cp = last_start; 5358 memmove(cp, "... ", 4); 5359 cp += 4; 5360 } 5361 } 5362 } 5363 if (!argv_count && !envp_count) 5364 break; 5365 } 5366 offset = 0; 5367 } 5368 *cp++ = '}'; 5369 *cp = '\0'; 5370 return buffer; 5371 out: 5372 snprintf(buffer, ccs_buffer_len - 1, "argv[]={ ... } envp[]= { ... }"); 5373 return buffer; 5374 } 5375 5376 /** 5377 * ccs_filetype - Get string representation of file type. 5378 * 5379 * @mode: Mode value for stat(). 5380 * 5381 * Returns file type string. 5382 */ 5383 static inline const char *ccs_filetype(const umode_t mode) 5384 { 5385 switch (mode & S_IFMT) { 5386 case S_IFREG: 5387 case 0: 5388 return ccs_condition_keyword[CCS_TYPE_IS_FILE]; 5389 case S_IFDIR: 5390 return ccs_condition_keyword[CCS_TYPE_IS_DIRECTORY]; 5391 case S_IFLNK: 5392 return ccs_condition_keyword[CCS_TYPE_IS_SYMLINK]; 5393 case S_IFIFO: 5394 return ccs_condition_keyword[CCS_TYPE_IS_FIFO]; 5395 case S_IFSOCK: 5396 return ccs_condition_keyword[CCS_TYPE_IS_SOCKET]; 5397 case S_IFBLK: 5398 return ccs_condition_keyword[CCS_TYPE_IS_BLOCK_DEV]; 5399 case S_IFCHR: 5400 return ccs_condition_keyword[CCS_TYPE_IS_CHAR_DEV]; 5401 } 5402 return "unknown"; /* This should not happen. */ 5403 } 5404 5405 /** 5406 * ccs_print_header - Get header line of audit log. 5407 * 5408 * @r: Pointer to "struct ccs_request_info". 5409 * 5410 * Returns string representation. 5411 * 5412 * This function uses kmalloc(), so caller must kfree() if this function 5413 * didn't return NULL. 5414 */ 5415 static char *ccs_print_header(struct ccs_request_info *r) 5416 { 5417 struct ccs_time stamp; 5418 struct ccs_obj_info *obj = r->obj; 5419 const u32 ccs_flags = ccs_current_flags(); 5420 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) 5421 const pid_t gpid = ccs_sys_getpid(); 5422 #else 5423 const pid_t gpid = task_pid_nr(current); 5424 #endif 5425 static const int ccs_buffer_len = 4096; 5426 char *buffer = kmalloc(ccs_buffer_len, CCS_GFP_FLAGS); 5427 int pos; 5428 u8 i; 5429 if (!buffer) 5430 return NULL; 5431 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 5432 { 5433 struct timeval tv; 5434 do_gettimeofday(&tv); 5435 ccs_convert_time(tv.tv_sec, &stamp); 5436 } 5437 #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) 5438 ccs_convert_time(get_seconds(), &stamp); 5439 #else 5440 ccs_convert_time(ktime_get_real_seconds(), &stamp); 5441 #endif 5442 pos = snprintf(buffer, ccs_buffer_len - 1, 5443 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s " 5444 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u " 5445 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u " 5446 "fsuid=%u fsgid=%u type%s=execute_handler }", 5447 stamp.year, stamp.month, stamp.day, stamp.hour, 5448 stamp.min, stamp.sec, r->profile, ccs_mode[r->mode], 5449 ccs_yesno(r->granted), gpid, ccs_sys_getpid(), 5450 ccs_sys_getppid(), 5451 from_kuid(&init_user_ns, current_uid()), 5452 from_kgid(&init_user_ns, current_gid()), 5453 from_kuid(&init_user_ns, current_euid()), 5454 from_kgid(&init_user_ns, current_egid()), 5455 from_kuid(&init_user_ns, current_suid()), 5456 from_kgid(&init_user_ns, current_sgid()), 5457 from_kuid(&init_user_ns, current_fsuid()), 5458 from_kgid(&init_user_ns, current_fsgid()), 5459 ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ? "" : "!"); 5460 if (!obj) 5461 goto no_obj_info; 5462 if (!obj->validate_done) { 5463 ccs_get_attributes(obj); 5464 obj->validate_done = true; 5465 } 5466 for (i = 0; i < CCS_MAX_PATH_STAT; i++) { 5467 struct ccs_mini_stat *stat; 5468 unsigned int dev; 5469 umode_t mode; 5470 if (!obj->stat_valid[i]) 5471 continue; 5472 stat = &obj->stat[i]; 5473 dev = stat->dev; 5474 mode = stat->mode; 5475 if (i & 1) { 5476 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, 5477 " path%u.parent={ uid=%u gid=%u " 5478 "ino=%lu perm=0%o }", (i >> 1) + 1, 5479 from_kuid(&init_user_ns, stat->uid), 5480 from_kgid(&init_user_ns, stat->gid), 5481 (unsigned long) stat->ino, 5482 stat->mode & S_IALLUGO); 5483 continue; 5484 } 5485 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, 5486 " path%u={ uid=%u gid=%u ino=%lu major=%u" 5487 " minor=%u perm=0%o type=%s", (i >> 1) + 1, 5488 from_kuid(&init_user_ns, stat->uid), 5489 from_kgid(&init_user_ns, stat->gid), 5490 (unsigned long) stat->ino, MAJOR(dev), 5491 MINOR(dev), mode & S_IALLUGO, 5492 ccs_filetype(mode)); 5493 if (S_ISCHR(mode) || S_ISBLK(mode)) { 5494 dev = stat->rdev; 5495 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, 5496 " dev_major=%u dev_minor=%u", 5497 MAJOR(dev), MINOR(dev)); 5498 } 5499 pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, " }"); 5500 } 5501 no_obj_info: 5502 if (pos < ccs_buffer_len - 1) 5503 return buffer; 5504 kfree(buffer); 5505 return NULL; 5506 } 5507 5508 /** 5509 * ccs_init_log - Allocate buffer for audit logs. 5510 * 5511 * @r: Pointer to "struct ccs_request_info". 5512 * @len: Buffer size needed for @fmt and @args. 5513 * @fmt: The printf()'s format string. 5514 * @args: va_list structure for @fmt. 5515 * 5516 * Returns pointer to allocated memory. 5517 * 5518 * This function uses kzalloc(), so caller must kfree() if this function 5519 * didn't return NULL. 5520 */ 5521 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt, 5522 va_list args) 5523 { 5524 char *buf = NULL; 5525 char *bprm_info = NULL; 5526 char *realpath = NULL; 5527 const char *symlink = NULL; 5528 const char *header = NULL; 5529 int pos; 5530 const char *domainname = ccs_current_domain()->domainname->name; 5531 header = ccs_print_header(r); 5532 if (!header) 5533 return NULL; 5534 /* +10 is for '\n' etc. and '\0'. */ 5535 len += strlen(domainname) + strlen(header) + 10; 5536 if (r->ee) { 5537 struct file *file = r->ee->bprm->file; 5538 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) 5539 struct path path = { file->f_vfsmnt, file->f_dentry }; 5540 realpath = ccs_realpath(&path); 5541 #else 5542 realpath = ccs_realpath(&file->f_path); 5543 #endif 5544 bprm_info = ccs_print_bprm(r->ee->bprm, &r->ee->dump); 5545 if (!realpath || !bprm_info) 5546 goto out; 5547 /* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */ 5548 len += strlen(realpath) + 80 + strlen(bprm_info); 5549 } else if (r->obj && r->obj->symlink_target) { 5550 symlink = r->obj->symlink_target->name; 5551 /* +18 is for " symlink.target=\"%s\"" */ 5552 len += 18 + strlen(symlink); 5553 } 5554 len = ccs_round2(len); 5555 buf = kzalloc(len, CCS_GFP_FLAGS); 5556 if (!buf) 5557 goto out; 5558 len--; 5559 pos = snprintf(buf, len, "%s", header); 5560 if (realpath) { 5561 struct linux_binprm *bprm = r->ee->bprm; 5562 pos += snprintf(buf + pos, len - pos, 5563 " exec={ realpath=\"%s\" argc=%d envc=%d %s }", 5564 realpath, bprm->argc, bprm->envc, bprm_info); 5565 } else if (symlink) 5566 pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"", 5567 symlink); 5568 pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname); 5569 vsnprintf(buf + pos, len - pos, fmt, args); 5570 out: 5571 kfree(realpath); 5572 kfree(bprm_info); 5573 kfree(header); 5574 return buf; 5575 } 5576 5577 /** 5578 * ccs_transition_failed - Print waning message and send signal when domain transition failed. 5579 * 5580 * @domainname: Name of domain to transit. 5581 * 5582 * Returns nothing. 5583 * 5584 * Note that if current->pid == 1, sending SIGKILL won't work. 5585 */ 5586 void ccs_transition_failed(const char *domainname) 5587 { 5588 printk(KERN_WARNING 5589 "ERROR: Unable to transit to '%s' domain.\n", domainname); 5590 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0) 5591 force_sig(SIGKILL, current); 5592 #else 5593 force_sig(SIGKILL); 5594 #endif 5595 } 5596 5597 /** 5598 * ccs_update_task_domain - Update task's domain. 5599 * 5600 * @r: Pointer to "struct ccs_request_info". 5601 * 5602 * Returns nothing. 5603 * 5604 * The task will retry as hard as possible. But if domain transition failed, 5605 * the task will be killed by SIGKILL. 5606 */ 5607 static void ccs_update_task_domain(struct ccs_request_info *r) 5608 { 5609 char *buf; 5610 const char *cp; 5611 const struct ccs_acl_info *acl = r->matched_acl; 5612 if (!acl || !acl->cond || !acl->cond->transit || 5613 acl->cond->exec_transit) 5614 return; 5615 while (1) { 5616 buf = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS); 5617 if (buf) 5618 break; 5619 ssleep(1); 5620 if (fatal_signal_pending(current)) 5621 return; 5622 } 5623 cp = acl->cond->transit->name; 5624 if (!ccs_domain_def(cp)) 5625 snprintf(buf, CCS_EXEC_TMPSIZE - 1, "%s %s", 5626 ccs_current_domain()->domainname->name, cp); 5627 else 5628 strncpy(buf, cp, CCS_EXEC_TMPSIZE - 1); 5629 if (!ccs_assign_domain(buf, true)) 5630 ccs_transition_failed(buf); 5631 kfree(buf); 5632 } 5633 5634 /** 5635 * ccs_get_audit - Get audit mode. 5636 * 5637 * @r: Pointer to "struct ccs_request_info". 5638 * 5639 * Returns true if this request should be audited, false otherwise. 5640 */ 5641 static bool ccs_get_audit(const struct ccs_request_info *r) 5642 { 5643 const struct ccs_acl_info *matched_acl = r->matched_acl; 5644 const u8 profile = r->profile; 5645 const u8 index = r->type; 5646 const bool is_granted = r->granted; 5647 u8 mode; 5648 struct ccs_profile *p; 5649 if (!ccs_policy_loaded) 5650 return false; 5651 p = ccs_profile(profile); 5652 if (ccs_log_count >= p->pref[CCS_PREF_MAX_AUDIT_LOG]) 5653 return false; 5654 if (is_granted && matched_acl && matched_acl->cond && 5655 matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO) 5656 return matched_acl->cond->grant_log == CCS_GRANTLOG_YES; 5657 mode = p->config[index]; 5658 if (mode == CCS_CONFIG_USE_DEFAULT) 5659 mode = p->config 5660 [ccs_index2category[index] + CCS_MAX_MAC_INDEX]; 5661 if (mode == CCS_CONFIG_USE_DEFAULT) 5662 mode = p->default_config; 5663 if (is_granted) 5664 return mode & CCS_CONFIG_WANT_GRANT_LOG; 5665 return mode & CCS_CONFIG_WANT_REJECT_LOG; 5666 } 5667 5668 /** 5669 * ccs_write_log2 - Write an audit log. 5670 * 5671 * @r: Pointer to "struct ccs_request_info". 5672 * @len: Buffer size needed for @fmt and @args. 5673 * @fmt: The printf()'s format string. 5674 * @args: va_list structure for @fmt. 5675 * 5676 * Returns nothing. 5677 */ 5678 static void ccs_write_log2(struct ccs_request_info *r, int len, 5679 const char *fmt, va_list args) 5680 { 5681 char *buf; 5682 struct ccs_log *entry; 5683 bool quota_exceeded = false; 5684 if (!ccs_get_audit(r)) 5685 goto out; 5686 buf = ccs_init_log(r, len, fmt, args); 5687 if (!buf) 5688 goto out; 5689 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS); 5690 if (!entry) { 5691 kfree(buf); 5692 goto out; 5693 } 5694 entry->log = buf; 5695 len = ccs_round2(strlen(buf) + 1); 5696 /* 5697 * The entry->size is used for memory quota checks. 5698 * Don't go beyond strlen(entry->log). 5699 */ 5700 entry->size = len + ccs_round2(sizeof(*entry)); 5701 spin_lock(&ccs_log_lock); 5702 if (ccs_memory_quota[CCS_MEMORY_AUDIT] && 5703 ccs_memory_used[CCS_MEMORY_AUDIT] + entry->size >= 5704 ccs_memory_quota[CCS_MEMORY_AUDIT]) { 5705 quota_exceeded = true; 5706 } else { 5707 ccs_memory_used[CCS_MEMORY_AUDIT] += entry->size; 5708 list_add_tail(&entry->list, &ccs_log); 5709 ccs_log_count++; 5710 } 5711 spin_unlock(&ccs_log_lock); 5712 if (quota_exceeded) { 5713 kfree(buf); 5714 kfree(entry); 5715 goto out; 5716 } 5717 wake_up(&ccs_log_wait); 5718 out: 5719 ccs_update_task_domain(r); 5720 } 5721 5722 /** 5723 * ccs_write_log - Write an audit log. 5724 * 5725 * @r: Pointer to "struct ccs_request_info". 5726 * @fmt: The printf()'s format string, followed by parameters. 5727 * 5728 * Returns nothing. 5729 */ 5730 void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...) 5731 { 5732 va_list args; 5733 int len; 5734 va_start(args, fmt); 5735 len = vsnprintf((char *) &len, 1, fmt, args) + 1; 5736 va_end(args); 5737 va_start(args, fmt); 5738 ccs_write_log2(r, len, fmt, args); 5739 va_end(args); 5740 } 5741 5742 /** 5743 * ccs_read_log - Read an audit log. 5744 * 5745 * @head: Pointer to "struct ccs_io_buffer". 5746 * 5747 * Returns nothing. 5748 */ 5749 static void ccs_read_log(struct ccs_io_buffer *head) 5750 { 5751 struct ccs_log *ptr = NULL; 5752 if (head->r.w_pos) 5753 return; 5754 kfree(head->read_buf); 5755 head->read_buf = NULL; 5756 spin_lock(&ccs_log_lock); 5757 if (!list_empty(&ccs_log)) { 5758 ptr = list_entry(ccs_log.next, typeof(*ptr), list); 5759 list_del(&ptr->list); 5760 ccs_log_count--; 5761 ccs_memory_used[CCS_MEMORY_AUDIT] -= ptr->size; 5762 } 5763 spin_unlock(&ccs_log_lock); 5764 if (ptr) { 5765 head->read_buf = ptr->log; 5766 head->r.w[head->r.w_pos++] = head->read_buf; 5767 kfree(ptr); 5768 } 5769 } 5770 5771 /** 5772 * ccs_set_namespace_cursor - Set namespace to read. 5773 * 5774 * @head: Pointer to "struct ccs_io_buffer". 5775 * 5776 * Returns nothing. 5777 */ 5778 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head) 5779 { 5780 struct list_head *ns; 5781 if (head->type != CCS_EXCEPTION_POLICY && head->type != CCS_PROFILE) 5782 return; 5783 /* 5784 * If this is the first read, or reading previous namespace finished 5785 * and has more namespaces to read, update the namespace cursor. 5786 */ 5787 ns = head->r.ns; 5788 if (!ns || (head->r.eof && ns->next != &ccs_namespace_list)) { 5789 /* Clearing is OK because ccs_flush() returned true. */ 5790 memset(&head->r, 0, sizeof(head->r)); 5791 head->r.ns = ns ? ns->next : ccs_namespace_list.next; 5792 } 5793 } 5794 5795 /** 5796 * ccs_has_more_namespace - Check for unread namespaces. 5797 * 5798 * @head: Pointer to "struct ccs_io_buffer". 5799 * 5800 * Returns true if we have more entries to print, false otherwise. 5801 */ 5802 static bool ccs_has_more_namespace(struct ccs_io_buffer *head) 5803 { 5804 return (head->type == CCS_EXCEPTION_POLICY || 5805 head->type == CCS_PROFILE) && head->r.eof && 5806 head->r.ns->next != &ccs_namespace_list; 5807 } 5808 5809 /** 5810 * ccs_find_namespace - Find specified namespace. 5811 * 5812 * @name: Name of namespace to find. 5813 * @len: Length of @name. 5814 * 5815 * Returns pointer to "struct ccs_policy_namespace" if found, NULL otherwise. 5816 * 5817 * Caller holds ccs_read_lock(). 5818 */ 5819 static struct ccs_policy_namespace *ccs_find_namespace(const char *name, 5820 const unsigned int len) 5821 { 5822 struct ccs_policy_namespace *ns; 5823 list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list, 5824 &ccs_ss) { 5825 if (strncmp(name, ns->name, len) || 5826 (name[len] && name[len] != ' ')) 5827 continue; 5828 return ns; 5829 } 5830 return NULL; 5831 } 5832 5833 /** 5834 * ccs_assign_namespace - Create a new namespace. 5835 * 5836 * @domainname: Name of namespace to create. 5837 * 5838 * Returns pointer to "struct ccs_policy_namespace" on success, NULL otherwise. 5839 * 5840 * Caller holds ccs_read_lock(). 5841 */ 5842 static struct ccs_policy_namespace *ccs_assign_namespace 5843 (const char *domainname) 5844 { 5845 struct ccs_policy_namespace *ptr; 5846 struct ccs_policy_namespace *entry; 5847 const char *cp = domainname; 5848 unsigned int len = 0; 5849 while (*cp && *cp++ != ' ') 5850 len++; 5851 ptr = ccs_find_namespace(domainname, len); 5852 if (ptr) 5853 return ptr; 5854 if (len >= CCS_EXEC_TMPSIZE - 10 || !ccs_domain_def(domainname)) 5855 return NULL; 5856 entry = kzalloc(sizeof(*entry) + len + 1, CCS_GFP_FLAGS); 5857 if (!entry) 5858 return NULL; 5859 if (mutex_lock_interruptible(&ccs_policy_lock)) 5860 goto out; 5861 ptr = ccs_find_namespace(domainname, len); 5862 if (!ptr && ccs_memory_ok(entry, sizeof(*entry) + len + 1)) { 5863 char *name = (char *) (entry + 1); 5864 ptr = entry; 5865 memmove(name, domainname, len); 5866 name[len] = '\0'; 5867 entry->name = name; 5868 ccs_init_policy_namespace(entry); 5869 entry = NULL; 5870 } 5871 mutex_unlock(&ccs_policy_lock); 5872 out: 5873 kfree(entry); 5874 return ptr; 5875 } 5876 5877 /** 5878 * ccs_namespace_jump - Check for namespace jump. 5879 * 5880 * @domainname: Name of domain. 5881 * 5882 * Returns true if namespace differs, false otherwise. 5883 */ 5884 static bool ccs_namespace_jump(const char *domainname) 5885 { 5886 const char *namespace = ccs_current_namespace()->name; 5887 const int len = strlen(namespace); 5888 return strncmp(domainname, namespace, len) || 5889 (domainname[len] && domainname[len] != ' '); 5890 } 5891 5892 /** 5893 * ccs_assign_domain - Create a domain or a namespace. 5894 * 5895 * @domainname: The name of domain. 5896 * @transit: True if transit to domain found or created. 5897 * 5898 * Returns pointer to "struct ccs_domain_info" on success, NULL otherwise. 5899 * 5900 * Caller holds ccs_read_lock(). 5901 */ 5902 struct ccs_domain_info *ccs_assign_domain(const char *domainname, 5903 const bool transit) 5904 { 5905 struct ccs_security *security = ccs_current_security(); 5906 struct ccs_domain_info e = { }; 5907 struct ccs_domain_info *entry = ccs_find_domain(domainname); 5908 bool created = false; 5909 if (entry) { 5910 if (transit) { 5911 /* 5912 * Since namespace is created at runtime, profiles may 5913 * not be created by the moment the process transits to 5914 * that domain. Do not perform domain transition if 5915 * profile for that domain is not yet created. 5916 */ 5917 if (ccs_policy_loaded && 5918 !entry->ns->profile_ptr[entry->profile]) 5919 return NULL; 5920 security->ccs_domain_info = entry; 5921 } 5922 return entry; 5923 } 5924 /* Requested domain does not exist. */ 5925 /* Don't create requested domain if domainname is invalid. */ 5926 if (strlen(domainname) >= CCS_EXEC_TMPSIZE - 10 || 5927 !ccs_correct_domain(domainname)) 5928 return NULL; 5929 /* 5930 * Since definition of profiles and acl_groups may differ across 5931 * namespaces, do not inherit "use_profile" and "use_group" settings 5932 * by automatically creating requested domain upon domain transition. 5933 */ 5934 if (transit && ccs_namespace_jump(domainname)) 5935 return NULL; 5936 e.ns = ccs_assign_namespace(domainname); 5937 if (!e.ns) 5938 return NULL; 5939 /* 5940 * "use_profile" and "use_group" settings for automatically created 5941 * domains are inherited from current domain. These are 0 for manually 5942 * created domains. 5943 */ 5944 if (transit) { 5945 const struct ccs_domain_info *domain = 5946 security->ccs_domain_info; 5947 e.profile = domain->profile; 5948 memcpy(e.group, domain->group, sizeof(e.group)); 5949 } 5950 e.domainname = ccs_get_name(domainname); 5951 if (!e.domainname) 5952 return NULL; 5953 if (mutex_lock_interruptible(&ccs_policy_lock)) 5954 goto out; 5955 entry = ccs_find_domain(domainname); 5956 if (!entry) { 5957 entry = ccs_commit_ok(&e, sizeof(e)); 5958 if (entry) { 5959 INIT_LIST_HEAD(&entry->acl_info_list); 5960 list_add_tail_rcu(&entry->list, &ccs_domain_list); 5961 created = true; 5962 } 5963 } 5964 mutex_unlock(&ccs_policy_lock); 5965 out: 5966 ccs_put_name(e.domainname); 5967 if (entry && transit) { 5968 security->ccs_domain_info = entry; 5969 if (created) { 5970 struct ccs_request_info r; 5971 int i; 5972 ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE); 5973 r.granted = false; 5974 ccs_write_log(&r, "use_profile %u\n", entry->profile); 5975 for (i = 0; i < CCS_MAX_ACL_GROUPS; i++) 5976 if (test_bit(i, entry->group)) 5977 ccs_write_log(&r, "use_group %u\n", i); 5978 ccs_update_stat(CCS_STAT_POLICY_UPDATES); 5979 } 5980 } 5981 return entry; 5982 } 5983 5984 /** 5985 * ccs_parse_policy - Parse a policy line. 5986 * 5987 * @head: Pointer to "struct ccs_io_buffer". 5988 * @line: Line to parse. 5989 * 5990 * Returns 0 on success, negative value otherwise. 5991 * 5992 * Caller holds ccs_read_lock(). 5993 */ 5994 static int ccs_parse_policy(struct ccs_io_buffer *head, char *line) 5995 { 5996 /* Delete request? */ 5997 head->w.is_delete = !strncmp(line, "delete ", 7); 5998 if (head->w.is_delete) 5999 memmove(line, line + 7, strlen(line + 7) + 1); 6000 /* Selecting namespace to update. */ 6001 if (head->type == CCS_EXCEPTION_POLICY || head->type == CCS_PROFILE) { 6002 if (*line == '<') { 6003 char *cp = strchr(line, ' '); 6004 if (cp) { 6005 *cp++ = '\0'; 6006 head->w.ns = ccs_assign_namespace(line); 6007 memmove(line, cp, strlen(cp) + 1); 6008 } else 6009 head->w.ns = NULL; 6010 } else 6011 head->w.ns = &ccs_kernel_namespace; 6012 /* Don't allow updating if namespace is invalid. */ 6013 if (!head->w.ns) 6014 return -ENOENT; 6015 } 6016 /* Do the update. */ 6017 switch (head->type) { 6018 case CCS_DOMAIN_POLICY: 6019 return ccs_write_domain(head); 6020 case CCS_EXCEPTION_POLICY: 6021 return ccs_write_exception(head); 6022 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 6023 case CCS_EXECUTE_HANDLER: 6024 #endif 6025 case CCS_PROCESS_STATUS: 6026 return ccs_write_pid(head); 6027 case CCS_STAT: 6028 return ccs_write_stat(head); 6029 case CCS_PROFILE: 6030 return ccs_write_profile(head); 6031 case CCS_QUERY: 6032 return ccs_write_answer(head); 6033 case CCS_MANAGER: 6034 return ccs_write_manager(head); 6035 default: 6036 return -EINVAL; 6037 } 6038 } 6039 6040 /** 6041 * ccs_policy_io_init - Register hooks for policy I/O. 6042 * 6043 * Returns nothing. 6044 */ 6045 static void __init ccs_policy_io_init(void) 6046 { 6047 ccsecurity_ops.check_profile = ccs_check_profile; 6048 } 6049 6050 /** 6051 * ccs_load_builtin_policy - Load built-in policy. 6052 * 6053 * Returns nothing. 6054 */ 6055 static void __init ccs_load_builtin_policy(void) 6056 { 6057 /* 6058 * This include file is manually created and contains built-in policy 6059 * named "ccs_builtin_profile", "ccs_builtin_exception_policy", 6060 * "ccs_builtin_domain_policy", "ccs_builtin_manager", 6061 * "ccs_builtin_stat" in the form of "static char [] __initdata". 6062 */ 6063 #include "builtin-policy.h" 6064 u8 i; 6065 const int idx = ccs_read_lock(); 6066 for (i = 0; i < 5; i++) { 6067 struct ccs_io_buffer head = { }; 6068 char *start = ""; 6069 switch (i) { 6070 case 0: 6071 start = ccs_builtin_profile; 6072 head.type = CCS_PROFILE; 6073 break; 6074 case 1: 6075 start = ccs_builtin_exception_policy; 6076 head.type = CCS_EXCEPTION_POLICY; 6077 break; 6078 case 2: 6079 start = ccs_builtin_domain_policy; 6080 head.type = CCS_DOMAIN_POLICY; 6081 break; 6082 case 3: 6083 start = ccs_builtin_manager; 6084 head.type = CCS_MANAGER; 6085 break; 6086 case 4: 6087 start = ccs_builtin_stat; 6088 head.type = CCS_STAT; 6089 break; 6090 } 6091 while (1) { 6092 char *end = strchr(start, '\n'); 6093 if (!end) 6094 break; 6095 *end = '\0'; 6096 ccs_normalize_line(start); 6097 head.write_buf = start; 6098 ccs_parse_policy(&head, start); 6099 start = end + 1; 6100 } 6101 } 6102 ccs_read_unlock(idx); 6103 #ifdef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER 6104 ccs_check_profile(); 6105 #endif 6106 } 6107 6108 /** 6109 * ccs_read_self - read() for /proc/ccs/self_domain interface. 6110 * 6111 * @file: Pointer to "struct file". 6112 * @buf: Domainname which current thread belongs to. 6113 * @count: Size of @buf. 6114 * @ppos: Bytes read by now. 6115 * 6116 * Returns read size on success, negative value otherwise. 6117 */ 6118 static ssize_t ccs_read_self(struct file *file, char __user *buf, size_t count, 6119 loff_t *ppos) 6120 { 6121 const char *domain = ccs_current_domain()->domainname->name; 6122 loff_t len = strlen(domain); 6123 loff_t pos = *ppos; 6124 if (pos >= len || !count) 6125 return 0; 6126 len -= pos; 6127 if (count < len) 6128 len = count; 6129 if (copy_to_user(buf, domain + pos, len)) 6130 return -EFAULT; 6131 *ppos += len; 6132 return len; 6133 } 6134 6135 /** 6136 * ccs_open - open() for /proc/ccs/ interface. 6137 * 6138 * @inode: Pointer to "struct inode". 6139 * @file: Pointer to "struct file". 6140 * 6141 * Returns 0 on success, negative value otherwise. 6142 */ 6143 static int ccs_open(struct inode *inode, struct file *file) 6144 { 6145 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) || (defined(RHEL_MAJOR) && RHEL_MAJOR == 9 && defined(RHEL_MINOR) && RHEL_MINOR >= 1) 6146 const u8 type = (unsigned long) pde_data(inode); 6147 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) 6148 const u8 type = (unsigned long) PDE_DATA(inode); 6149 #else 6150 const u8 type = (unsigned long) PDE(inode)->data; 6151 #endif 6152 struct ccs_io_buffer *head = kzalloc(sizeof(*head), CCS_GFP_FLAGS); 6153 if (!head) 6154 return -ENOMEM; 6155 mutex_init(&head->io_sem); 6156 head->type = type; 6157 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 6158 if (type == CCS_EXECUTE_HANDLER) { 6159 /* Allow execute_handler to read process's status. */ 6160 if (!(ccs_current_flags() & CCS_TASK_IS_EXECUTE_HANDLER)) { 6161 kfree(head); 6162 return -EPERM; 6163 } 6164 } 6165 #endif 6166 if ((file->f_mode & FMODE_READ) && type != CCS_AUDIT && 6167 type != CCS_QUERY) { 6168 /* Don't allocate read_buf for poll() access. */ 6169 head->readbuf_size = 4096; 6170 head->read_buf = kzalloc(head->readbuf_size, CCS_GFP_FLAGS); 6171 if (!head->read_buf) { 6172 kfree(head); 6173 return -ENOMEM; 6174 } 6175 } 6176 if (file->f_mode & FMODE_WRITE) { 6177 head->writebuf_size = 4096; 6178 head->write_buf = kzalloc(head->writebuf_size, CCS_GFP_FLAGS); 6179 if (!head->write_buf) { 6180 kfree(head->read_buf); 6181 kfree(head); 6182 return -ENOMEM; 6183 } 6184 } 6185 /* 6186 * If the file is /proc/ccs/query, increment the observer counter. 6187 * The obserber counter is used by ccs_supervisor() to see if 6188 * there is some process monitoring /proc/ccs/query. 6189 */ 6190 if (type == CCS_QUERY) 6191 atomic_inc(&ccs_query_observers); 6192 file->private_data = head; 6193 ccs_notify_gc(head, true); 6194 return 0; 6195 } 6196 6197 /** 6198 * ccs_release - close() for /proc/ccs/ interface. 6199 * 6200 * @inode: Pointer to "struct inode". 6201 * @file: Pointer to "struct file". 6202 * 6203 * Returns 0. 6204 */ 6205 static int ccs_release(struct inode *inode, struct file *file) 6206 { 6207 struct ccs_io_buffer *head = file->private_data; 6208 /* 6209 * If the file is /proc/ccs/query, decrement the observer counter. 6210 */ 6211 if (head->type == CCS_QUERY && 6212 atomic_dec_and_test(&ccs_query_observers)) 6213 wake_up_all(&ccs_answer_wait); 6214 ccs_notify_gc(head, false); 6215 return 0; 6216 } 6217 6218 /** 6219 * ccs_poll - poll() for /proc/ccs/ interface. 6220 * 6221 * @file: Pointer to "struct file". 6222 * @wait: Pointer to "poll_table". Maybe NULL. 6223 * 6224 * Returns POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM if ready to read/write, 6225 * POLLOUT | POLLWRNORM otherwise. 6226 */ 6227 static unsigned int ccs_poll(struct file *file, poll_table *wait) 6228 { 6229 struct ccs_io_buffer *head = file->private_data; 6230 if (head->type == CCS_AUDIT) { 6231 if (!ccs_memory_used[CCS_MEMORY_AUDIT]) { 6232 poll_wait(file, &ccs_log_wait, wait); 6233 if (!ccs_memory_used[CCS_MEMORY_AUDIT]) 6234 return POLLOUT | POLLWRNORM; 6235 } 6236 } else if (head->type == CCS_QUERY) { 6237 if (list_empty(&ccs_query_list)) { 6238 poll_wait(file, &ccs_query_wait, wait); 6239 if (list_empty(&ccs_query_list)) 6240 return POLLOUT | POLLWRNORM; 6241 } 6242 } 6243 return POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; 6244 } 6245 6246 /** 6247 * ccs_read - read() for /proc/ccs/ interface. 6248 * 6249 * @file: Pointer to "struct file". 6250 * @buf: Pointer to buffer. 6251 * @count: Size of @buf. 6252 * @ppos: Unused. 6253 * 6254 * Returns bytes read on success, negative value otherwise. 6255 */ 6256 static ssize_t ccs_read(struct file *file, char __user *buf, size_t count, 6257 loff_t *ppos) 6258 { 6259 struct ccs_io_buffer *head = file->private_data; 6260 int len; 6261 int idx; 6262 if (mutex_lock_interruptible(&head->io_sem)) 6263 return -EINTR; 6264 head->read_user_buf = buf; 6265 head->read_user_buf_avail = count; 6266 idx = ccs_read_lock(); 6267 if (ccs_flush(head)) 6268 /* Call the policy handler. */ 6269 do { 6270 ccs_set_namespace_cursor(head); 6271 switch (head->type) { 6272 case CCS_DOMAIN_POLICY: 6273 ccs_read_domain(head); 6274 break; 6275 case CCS_EXCEPTION_POLICY: 6276 ccs_read_exception(head); 6277 break; 6278 case CCS_AUDIT: 6279 ccs_read_log(head); 6280 break; 6281 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 6282 case CCS_EXECUTE_HANDLER: 6283 #endif 6284 case CCS_PROCESS_STATUS: 6285 ccs_read_pid(head); 6286 break; 6287 case CCS_VERSION: 6288 ccs_read_version(head); 6289 break; 6290 case CCS_STAT: 6291 ccs_read_stat(head); 6292 break; 6293 case CCS_PROFILE: 6294 ccs_read_profile(head); 6295 break; 6296 case CCS_QUERY: 6297 ccs_read_query(head); 6298 break; 6299 case CCS_MANAGER: 6300 ccs_read_manager(head); 6301 break; 6302 } 6303 } while (ccs_flush(head) && ccs_has_more_namespace(head)); 6304 ccs_read_unlock(idx); 6305 len = head->read_user_buf - buf; 6306 mutex_unlock(&head->io_sem); 6307 return len; 6308 } 6309 6310 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 6311 6312 /** 6313 * ccs_write_self - write() for /proc/ccs/self_domain interface. 6314 * 6315 * @file: Pointer to "struct file". 6316 * @buf: Domainname to transit to. 6317 * @count: Size of @buf. 6318 * @ppos: Unused. 6319 * 6320 * Returns @count on success, negative value otherwise. 6321 * 6322 * If domain transition was permitted but the domain transition failed, this 6323 * function returns error rather than terminating current thread with SIGKILL. 6324 */ 6325 static ssize_t ccs_write_self(struct file *file, const char __user *buf, 6326 size_t count, loff_t *ppos) 6327 { 6328 char *data; 6329 int error; 6330 if (!count || count >= CCS_EXEC_TMPSIZE - 10) 6331 return -ENOMEM; 6332 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) 6333 data = kzalloc(count + 1, CCS_GFP_FLAGS); 6334 if (!data) 6335 return -ENOMEM; 6336 if (copy_from_user(data, buf, count)) { 6337 error = -EFAULT; 6338 goto out; 6339 } 6340 #else 6341 data = memdup_user_nul(buf, count); 6342 if (IS_ERR(data)) 6343 return PTR_ERR(data); 6344 #endif 6345 ccs_normalize_line(data); 6346 if (ccs_correct_domain(data)) { 6347 const int idx = ccs_read_lock(); 6348 struct ccs_path_info name; 6349 struct ccs_request_info r; 6350 name.name = data; 6351 ccs_fill_path_info(&name); 6352 /* Check "task manual_domain_transition" permission. */ 6353 ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE); 6354 r.param_type = CCS_TYPE_MANUAL_TASK_ACL; 6355 r.param.task.domainname = &name; 6356 ccs_check_acl(&r); 6357 if (!r.granted) 6358 error = -EPERM; 6359 else 6360 error = ccs_assign_domain(data, true) ? 0 : -ENOENT; 6361 ccs_read_unlock(idx); 6362 } else 6363 error = -EINVAL; 6364 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0) 6365 out: 6366 #endif 6367 kfree(data); 6368 return error ? error : count; 6369 } 6370 6371 #endif 6372 6373 /** 6374 * ccs_write - write() for /proc/ccs/ interface. 6375 * 6376 * @file: Pointer to "struct file". 6377 * @buf: Pointer to buffer. 6378 * @count: Size of @buf. 6379 * @ppos: Unused. 6380 * 6381 * Returns @count on success, negative value otherwise. 6382 */ 6383 static ssize_t ccs_write(struct file *file, const char __user *buf, 6384 size_t count, loff_t *ppos) 6385 { 6386 struct ccs_io_buffer *head = file->private_data; 6387 int error = count; 6388 char *cp0; 6389 int idx; 6390 if (mutex_lock_interruptible(&head->io_sem)) 6391 return -EINTR; 6392 cp0 = head->write_buf; 6393 head->read_user_buf_avail = 0; 6394 idx = ccs_read_lock(); 6395 /* Read a line and dispatch it to the policy handler. */ 6396 while (count) { 6397 char c; 6398 if (head->w.avail >= head->writebuf_size - 1) { 6399 const int len = head->writebuf_size * 2; 6400 char *cp = kzalloc(len, CCS_GFP_FLAGS); 6401 if (!cp) { 6402 error = -ENOMEM; 6403 break; 6404 } 6405 memmove(cp, cp0, head->w.avail); 6406 kfree(cp0); 6407 head->write_buf = cp; 6408 cp0 = cp; 6409 head->writebuf_size = len; 6410 } 6411 if (get_user(c, buf)) { 6412 error = -EFAULT; 6413 break; 6414 } 6415 buf++; 6416 count--; 6417 cp0[head->w.avail++] = c; 6418 if (c != '\n') 6419 continue; 6420 cp0[head->w.avail - 1] = '\0'; 6421 head->w.avail = 0; 6422 ccs_normalize_line(cp0); 6423 if (!strcmp(cp0, "reset")) { 6424 head->w.ns = &ccs_kernel_namespace; 6425 head->w.domain = NULL; 6426 memset(&head->r, 0, sizeof(head->r)); 6427 continue; 6428 } 6429 /* Don't allow updating policies by non manager programs. */ 6430 switch (head->type) { 6431 case CCS_PROCESS_STATUS: 6432 /* This does not write anything. */ 6433 break; 6434 case CCS_DOMAIN_POLICY: 6435 if (ccs_select_domain(head, cp0)) 6436 continue; 6437 /* fall through */ 6438 fallthrough; 6439 case CCS_EXCEPTION_POLICY: 6440 if (!strcmp(cp0, "select transition_only")) { 6441 head->r.print_transition_related_only = true; 6442 continue; 6443 } 6444 /* fall through */ 6445 fallthrough; 6446 default: 6447 if (!ccs_manager()) { 6448 error = -EPERM; 6449 goto out; 6450 } 6451 } 6452 switch (ccs_parse_policy(head, cp0)) { 6453 case -EPERM: 6454 error = -EPERM; 6455 goto out; 6456 case 0: 6457 /* Update statistics. */ 6458 switch (head->type) { 6459 case CCS_DOMAIN_POLICY: 6460 case CCS_EXCEPTION_POLICY: 6461 case CCS_STAT: 6462 case CCS_PROFILE: 6463 case CCS_MANAGER: 6464 ccs_update_stat(CCS_STAT_POLICY_UPDATES); 6465 break; 6466 default: 6467 break; 6468 } 6469 break; 6470 } 6471 } 6472 out: 6473 ccs_read_unlock(idx); 6474 mutex_unlock(&head->io_sem); 6475 return error; 6476 } 6477 6478 /** 6479 * ccs_create_entry - Create interface files under /proc/ccs/ directory. 6480 * 6481 * @name: The name of the interface file. 6482 * @mode: The permission of the interface file. 6483 * @parent: The parent directory. 6484 * @key: Type of interface. 6485 * 6486 * Returns nothing. 6487 */ 6488 static void __init ccs_create_entry(const char *name, const umode_t mode, 6489 struct proc_dir_entry *parent, 6490 const u8 key) 6491 { 6492 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) 6493 proc_create_data(name, mode, parent, &ccs_operations, 6494 ((u8 *) NULL) + key); 6495 #else 6496 struct proc_dir_entry *entry = create_proc_entry(name, mode, parent); 6497 if (entry) { 6498 entry->proc_fops = &ccs_operations; 6499 entry->data = ((u8 *) NULL) + key; 6500 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 6501 if (entry->proc_iops) 6502 ccs_file_inode_operations = *entry->proc_iops; 6503 if (!ccs_file_inode_operations.setattr) 6504 ccs_file_inode_operations.setattr = proc_notify_change; 6505 entry->proc_iops = &ccs_file_inode_operations; 6506 #endif 6507 } 6508 #endif 6509 } 6510 6511 /** 6512 * ccs_proc_init - Initialize /proc/ccs/ interface. 6513 * 6514 * Returns nothing. 6515 */ 6516 static void __init ccs_proc_init(void) 6517 { 6518 struct proc_dir_entry *ccs_dir = proc_mkdir("ccs", NULL); 6519 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 6520 if (ccs_dir->proc_iops) 6521 ccs_dir_inode_operations = *ccs_dir->proc_iops; 6522 if (!ccs_dir_inode_operations.setattr) 6523 ccs_dir_inode_operations.setattr = proc_notify_change; 6524 ccs_dir->proc_iops = &ccs_dir_inode_operations; 6525 #endif 6526 ccs_create_entry("query", 0600, ccs_dir, CCS_QUERY); 6527 ccs_create_entry("domain_policy", 0600, ccs_dir, CCS_DOMAIN_POLICY); 6528 ccs_create_entry("exception_policy", 0600, ccs_dir, 6529 CCS_EXCEPTION_POLICY); 6530 ccs_create_entry("audit", 0400, ccs_dir, CCS_AUDIT); 6531 ccs_create_entry(".process_status", 0600, ccs_dir, 6532 CCS_PROCESS_STATUS); 6533 ccs_create_entry("stat", 0644, ccs_dir, CCS_STAT); 6534 ccs_create_entry("profile", 0600, ccs_dir, CCS_PROFILE); 6535 ccs_create_entry("manager", 0600, ccs_dir, CCS_MANAGER); 6536 ccs_create_entry("version", 0400, ccs_dir, CCS_VERSION); 6537 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 6538 ccs_create_entry(".execute_handler", 0666, ccs_dir, 6539 CCS_EXECUTE_HANDLER); 6540 #endif 6541 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) 6542 proc_create("self_domain", 0666, ccs_dir, &ccs_self_operations); 6543 #else 6544 { 6545 struct proc_dir_entry *e = create_proc_entry("self_domain", 6546 0666, ccs_dir); 6547 if (e) 6548 e->proc_fops = &ccs_self_operations; 6549 } 6550 #endif 6551 } 6552 6553 /** 6554 * ccs_init_module - Initialize this module. 6555 * 6556 * Returns 0 on success, negative value otherwise. 6557 */ 6558 static int __init ccs_init_module(void) 6559 { 6560 if (ccsecurity_ops.disabled) 6561 return -EINVAL; 6562 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 6563 MOD_INC_USE_COUNT; 6564 #endif 6565 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) 6566 if (init_srcu_struct(&ccs_ss)) 6567 panic("Out of memory."); 6568 #endif 6569 ccs_kernel_namespace.name = "<kernel>"; 6570 ccs_init_policy_namespace(&ccs_kernel_namespace); 6571 ccs_kernel_domain.ns = &ccs_kernel_namespace; 6572 INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list); 6573 ccs_mm_init(); 6574 ccs_policy_io_init(); 6575 ccs_permission_init(); 6576 ccs_proc_init(); 6577 ccs_load_builtin_policy(); 6578 return 0; 6579 } 6580 6581 MODULE_LICENSE("GPL"); 6582 module_init(ccs_init_module); 6583
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.