1 /* 2 * security/ccsecurity/policy_io.c 3 * 4 * Copyright (C) 2005-2012 NTT DATA CORPORATION 5 * 6 * Version: 1.8.5+ 2018/04/01 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 unsigned 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 static struct ccs_domain_info *ccs_find_domain(const char *domainname); 496 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial); 497 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param, 498 const u8 idx); 499 static struct ccs_policy_namespace *ccs_assign_namespace 500 (const char *domainname); 501 static struct ccs_policy_namespace *ccs_find_namespace(const char *name, 502 const unsigned int len); 503 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns, 504 const unsigned int profile); 505 static struct ccs_profile *ccs_profile(const u8 profile); 506 static u8 ccs_condition_type(const char *word); 507 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3); 508 static u8 ccs_parse_ulong(unsigned long *result, char **str); 509 static unsigned int ccs_poll(struct file *file, poll_table *wait); 510 static void __init ccs_create_entry(const char *name, const umode_t mode, 511 struct proc_dir_entry *parent, 512 const u8 key); 513 static void __init ccs_load_builtin_policy(void); 514 static void __init ccs_policy_io_init(void); 515 static void __init ccs_proc_init(void); 516 static void ccs_add_entry(char *header); 517 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...) 518 __printf(3, 4); 519 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...); 520 static void ccs_check_profile(void); 521 static void ccs_convert_time(time_t time, struct ccs_time *stamp); 522 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns); 523 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...) 524 __printf(2, 3); 525 static void ccs_normalize_line(unsigned char *buffer); 526 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config); 527 static void ccs_print_name_union(struct ccs_io_buffer *head, 528 const struct ccs_name_union *ptr); 529 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head, 530 const struct ccs_name_union *ptr); 531 static void ccs_print_namespace(struct ccs_io_buffer *head); 532 static void ccs_print_number_union(struct ccs_io_buffer *head, 533 const struct ccs_number_union *ptr); 534 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head, 535 const struct ccs_number_union *ptr); 536 static void ccs_read_domain(struct ccs_io_buffer *head); 537 static void ccs_read_exception(struct ccs_io_buffer *head); 538 static void ccs_read_log(struct ccs_io_buffer *head); 539 static void ccs_read_manager(struct ccs_io_buffer *head); 540 static void ccs_read_pid(struct ccs_io_buffer *head); 541 static void ccs_read_profile(struct ccs_io_buffer *head); 542 static void ccs_read_query(struct ccs_io_buffer *head); 543 static void ccs_read_stat(struct ccs_io_buffer *head); 544 static void ccs_read_version(struct ccs_io_buffer *head); 545 static void ccs_set_group(struct ccs_io_buffer *head, const char *category); 546 static void ccs_set_namespace_cursor(struct ccs_io_buffer *head); 547 static void ccs_set_slash(struct ccs_io_buffer *head); 548 static void ccs_set_space(struct ccs_io_buffer *head); 549 static void ccs_set_string(struct ccs_io_buffer *head, const char *string); 550 static void ccs_set_uint(unsigned int *i, const char *string, 551 const char *find); 552 static void ccs_update_stat(const u8 index); 553 static void ccs_update_task_domain(struct ccs_request_info *r); 554 static void ccs_write_log2(struct ccs_request_info *r, int len, 555 const char *fmt, va_list args); 556 557 #ifdef CONFIG_CCSECURITY_PORTRESERVE 558 static bool __ccs_lport_reserved(const u16 port); 559 static int ccs_write_reserved_port(struct ccs_acl_param *param); 560 #endif 561 562 #ifdef CONFIG_CCSECURITY_NETWORK 563 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param, 564 struct ccs_ipaddr_union *ptr); 565 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len, 566 const u32 *ip); 567 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len, 568 const struct in6_addr *ip); 569 static int ccs_write_inet_network(struct ccs_acl_param *param); 570 static int ccs_write_unix_network(struct ccs_acl_param *param); 571 static void ccs_print_ip(char *buf, const unsigned int size, 572 const struct ccs_ipaddr_union *ptr); 573 #endif 574 575 #ifdef CONFIG_CCSECURITY_CAPABILITY 576 static int ccs_write_capability(struct ccs_acl_param *param); 577 #endif 578 579 #ifdef CONFIG_CCSECURITY_MISC 580 static int ccs_write_misc(struct ccs_acl_param *param); 581 #endif 582 583 #ifdef CONFIG_CCSECURITY_IPC 584 static int ccs_write_ipc(struct ccs_acl_param *param); 585 #endif 586 587 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 588 static ssize_t ccs_write_self(struct file *file, const char __user *buf, 589 size_t count, loff_t *ppos); 590 #endif 591 592 /***** SECTION4: Standalone functions section *****/ 593 594 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) 595 596 /** 597 * fatal_signal_pending - Check whether SIGKILL is pending or not. 598 * 599 * @p: Pointer to "struct task_struct". 600 * 601 * Returns true if SIGKILL is pending on @p, false otherwise. 602 * 603 * This is for compatibility with older kernels. 604 */ 605 #define fatal_signal_pending(p) (signal_pending(p) && \ 606 sigismember(&p->pending.signal, SIGKILL)) 607 608 #endif 609 610 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 611 612 /** 613 * __wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. 614 * 615 * @wq: The waitqueue to wait on. 616 * @condition: A C expression for the event to wait for. 617 * @ret: Timeout, in jiffies. 618 * 619 * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a 620 * signal, and the remaining jiffies otherwise if the condition evaluated to 621 * true before the timeout elapsed. 622 * 623 * This is for compatibility with older kernels. 624 */ 625 #define __wait_event_interruptible_timeout(wq, condition, ret) \ 626 do { \ 627 wait_queue_t __wait; \ 628 init_waitqueue_entry(&__wait, current); \ 629 \ 630 add_wait_queue(&wq, &__wait); \ 631 for (;;) { \ 632 set_current_state(TASK_INTERRUPTIBLE); \ 633 if (condition) \ 634 break; \ 635 if (!signal_pending(current)) { \ 636 ret = schedule_timeout(ret); \ 637 if (!ret) \ 638 break; \ 639 continue; \ 640 } \ 641 ret = -ERESTARTSYS; \ 642 break; \ 643 } \ 644 current->state = TASK_RUNNING; \ 645 remove_wait_queue(&wq, &__wait); \ 646 } while (0) 647 648 /** 649 * wait_event_interruptible_timeout - Sleep until a condition gets true or a timeout elapses. 650 * 651 * @wq: The waitqueue to wait on. 652 * @condition: A C expression for the event to wait for. 653 * @timeout: Timeout, in jiffies. 654 * 655 * Returns 0 if the @timeout elapsed, -ERESTARTSYS if it was interrupted by a 656 * signal, and the remaining jiffies otherwise if the condition evaluated to 657 * true before the timeout elapsed. 658 * 659 * This is for compatibility with older kernels. 660 */ 661 #define wait_event_interruptible_timeout(wq, condition, timeout) \ 662 ({ \ 663 long __ret = timeout; \ 664 if (!(condition)) \ 665 __wait_event_interruptible_timeout(wq, condition, __ret); \ 666 __ret; \ 667 }) 668 669 #endif 670 671 /** 672 * ccs_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss. 673 * 674 * @time: Seconds since 1970/01/01 00:00:00. 675 * @stamp: Pointer to "struct ccs_time". 676 * 677 * Returns nothing. 678 * 679 * This function does not handle Y2038 problem. 680 */ 681 static void ccs_convert_time(time_t time, struct ccs_time *stamp) 682 { 683 static const u16 ccs_eom[2][12] = { 684 { 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 685 { 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 686 }; 687 u16 y; 688 u8 m; 689 bool r; 690 stamp->sec = time % 60; 691 time /= 60; 692 stamp->min = time % 60; 693 time /= 60; 694 stamp->hour = time % 24; 695 time /= 24; 696 for (y = 1970; ; y++) { 697 const unsigned short days = (y & 3) ? 365 : 366; 698 if (time < days) 699 break; 700 time -= days; 701 } 702 r = (y & 3) == 0; 703 for (m = 0; m < 11 && time >= ccs_eom[r][m]; m++); 704 if (m) 705 time -= ccs_eom[r][m - 1]; 706 stamp->year = y; 707 stamp->month = ++m; 708 stamp->day = ++time; 709 } 710 711 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23) 712 #if !defined(RHEL_VERSION) || RHEL_VERSION != 3 713 714 /** 715 * PDE - Get "struct proc_dir_entry". 716 * 717 * @inode: Pointer to "struct inode". 718 * 719 * Returns pointer to "struct proc_dir_entry". 720 * 721 * This is for compatibility with older kernels. 722 */ 723 static inline struct proc_dir_entry *PDE(const struct inode *inode) 724 { 725 return (struct proc_dir_entry *) inode->u.generic_ip; 726 } 727 728 #endif 729 #endif 730 731 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 732 733 /** 734 * proc_notify_change - Update inode's attributes and reflect to the dentry. 735 * 736 * @dentry: Pointer to "struct dentry". 737 * @iattr: Pointer to "struct iattr". 738 * 739 * Returns 0 on success, negative value otherwise. 740 * 741 * The 2.4 kernels don't allow chmod()/chown() for files in /proc, 742 * while the 2.6 kernels allow. 743 * To permit management of /proc/ccs/ interface by non-root user, 744 * I modified to allow chmod()/chown() of /proc/ccs/ interface like 2.6 kernels 745 * by adding "struct inode_operations"->setattr hook. 746 */ 747 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) 748 { 749 struct inode *inode = dentry->d_inode; 750 struct proc_dir_entry *de = PDE(inode); 751 int error; 752 753 error = inode_change_ok(inode, iattr); 754 if (error) 755 goto out; 756 757 error = inode_setattr(inode, iattr); 758 if (error) 759 goto out; 760 761 de->uid = inode->i_uid; 762 de->gid = inode->i_gid; 763 de->mode = inode->i_mode; 764 out: 765 return error; 766 } 767 768 #endif 769 770 #ifdef CONFIG_CCSECURITY_NETWORK 771 772 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && defined(CONFIG_NET) 773 #define ccs_in4_pton in4_pton 774 #define ccs_in6_pton in6_pton 775 #else 776 /* 777 * Routines for parsing IPv4 or IPv6 address. 778 * These are copied from lib/hexdump.c net/core/utils.c . 779 */ 780 #include <linux/ctype.h> 781 782 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) 783 static int hex_to_bin(char ch) 784 { 785 if ((ch >= '') && (ch <= '9')) 786 return ch - ''; 787 ch = tolower(ch); 788 if ((ch >= 'a') && (ch <= 'f')) 789 return ch - 'a' + 10; 790 return -1; 791 } 792 #endif 793 794 #define IN6PTON_XDIGIT 0x00010000 795 #define IN6PTON_DIGIT 0x00020000 796 #define IN6PTON_COLON_MASK 0x00700000 797 #define IN6PTON_COLON_1 0x00100000 /* single : requested */ 798 #define IN6PTON_COLON_2 0x00200000 /* second : requested */ 799 #define IN6PTON_COLON_1_2 0x00400000 /* :: requested */ 800 #define IN6PTON_DOT 0x00800000 /* . */ 801 #define IN6PTON_DELIM 0x10000000 802 #define IN6PTON_NULL 0x20000000 /* first/tail */ 803 #define IN6PTON_UNKNOWN 0x40000000 804 805 static inline int xdigit2bin(char c, int delim) 806 { 807 int val; 808 809 if (c == delim || c == '\0') 810 return IN6PTON_DELIM; 811 if (c == ':') 812 return IN6PTON_COLON_MASK; 813 if (c == '.') 814 return IN6PTON_DOT; 815 816 val = hex_to_bin(c); 817 if (val >= 0) 818 return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0); 819 820 if (delim == -1) 821 return IN6PTON_DELIM; 822 return IN6PTON_UNKNOWN; 823 } 824 825 static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim, 826 const char **end) 827 { 828 const char *s; 829 u8 *d; 830 u8 dbuf[4]; 831 int ret = 0; 832 int i; 833 int w = 0; 834 835 if (srclen < 0) 836 srclen = strlen(src); 837 s = src; 838 d = dbuf; 839 i = 0; 840 while (1) { 841 int c; 842 c = xdigit2bin(srclen > 0 ? *s : '\0', delim); 843 if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | 844 IN6PTON_COLON_MASK))) 845 goto out; 846 if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 847 if (w == 0) 848 goto out; 849 *d++ = w & 0xff; 850 w = 0; 851 i++; 852 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 853 if (i != 4) 854 goto out; 855 break; 856 } 857 goto cont; 858 } 859 w = (w * 10) + c; 860 if ((w & 0xffff) > 255) 861 goto out; 862 cont: 863 if (i >= 4) 864 goto out; 865 s++; 866 srclen--; 867 } 868 ret = 1; 869 memcpy(dst, dbuf, sizeof(dbuf)); 870 out: 871 if (end) 872 *end = s; 873 return ret; 874 } 875 876 static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim, 877 const char **end) 878 { 879 const char *s, *tok = NULL; 880 u8 *d, *dc = NULL; 881 u8 dbuf[16]; 882 int ret = 0; 883 int i; 884 int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL; 885 int w = 0; 886 887 memset(dbuf, 0, sizeof(dbuf)); 888 889 s = src; 890 d = dbuf; 891 if (srclen < 0) 892 srclen = strlen(src); 893 894 while (1) { 895 int c; 896 897 c = xdigit2bin(srclen > 0 ? *s : '\0', delim); 898 if (!(c & state)) 899 goto out; 900 if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) { 901 /* process one 16-bit word */ 902 if (!(state & IN6PTON_NULL)) { 903 *d++ = (w >> 8) & 0xff; 904 *d++ = w & 0xff; 905 } 906 w = 0; 907 if (c & IN6PTON_DELIM) { 908 /* We've processed last word */ 909 break; 910 } 911 /* 912 * COLON_1 => XDIGIT 913 * COLON_2 => XDIGIT|DELIM 914 * COLON_1_2 => COLON_2 915 */ 916 switch (state & IN6PTON_COLON_MASK) { 917 case IN6PTON_COLON_2: 918 dc = d; 919 state = IN6PTON_XDIGIT | IN6PTON_DELIM; 920 if (dc - dbuf >= sizeof(dbuf)) 921 state |= IN6PTON_NULL; 922 break; 923 case IN6PTON_COLON_1|IN6PTON_COLON_1_2: 924 state = IN6PTON_XDIGIT | IN6PTON_COLON_2; 925 break; 926 case IN6PTON_COLON_1: 927 state = IN6PTON_XDIGIT; 928 break; 929 case IN6PTON_COLON_1_2: 930 state = IN6PTON_COLON_2; 931 break; 932 default: 933 state = 0; 934 } 935 tok = s + 1; 936 goto cont; 937 } 938 939 if (c & IN6PTON_DOT) { 940 ret = ccs_in4_pton(tok ? tok : s, srclen + 941 (int)(s - tok), d, delim, &s); 942 if (ret > 0) { 943 d += 4; 944 break; 945 } 946 goto out; 947 } 948 949 w = (w << 4) | (0xff & c); 950 state = IN6PTON_COLON_1 | IN6PTON_DELIM; 951 if (!(w & 0xf000)) 952 state |= IN6PTON_XDIGIT; 953 if (!dc && d + 2 < dbuf + sizeof(dbuf)) { 954 state |= IN6PTON_COLON_1_2; 955 state &= ~IN6PTON_DELIM; 956 } 957 if (d + 2 >= dbuf + sizeof(dbuf)) 958 state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2); 959 cont: 960 if ((dc && d + 4 < dbuf + sizeof(dbuf)) || 961 d + 4 == dbuf + sizeof(dbuf)) 962 state |= IN6PTON_DOT; 963 if (d >= dbuf + sizeof(dbuf)) 964 state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK); 965 s++; 966 srclen--; 967 } 968 969 i = 15; d--; 970 971 if (dc) { 972 while (d >= dc) 973 dst[i--] = *d--; 974 while (i >= dc - dbuf) 975 dst[i--] = 0; 976 while (i >= 0) 977 dst[i--] = *d--; 978 } else 979 memcpy(dst, dbuf, sizeof(dbuf)); 980 981 ret = 1; 982 out: 983 if (end) 984 *end = s; 985 return ret; 986 } 987 #endif 988 989 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) 990 991 /* 992 * Routines for printing IPv4 or IPv6 address. 993 * These are copied from include/linux/kernel.h include/net/ipv6.h 994 * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified. 995 */ 996 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) 997 #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5 || !defined(RHEL_MINOR) || RHEL_MINOR < 9 998 static const char hex_asc[] = "0123456789abcdef"; 999 #define hex_asc_lo(x) hex_asc[((x) & 0x0f)] 1000 #define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] 1001 1002 static inline char *pack_hex_byte(char *buf, u8 byte) 1003 { 1004 *buf++ = hex_asc_hi(byte); 1005 *buf++ = hex_asc_lo(byte); 1006 return buf; 1007 } 1008 #endif 1009 #endif 1010 1011 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) 1012 static inline int ipv6_addr_v4mapped(const struct in6_addr *a) 1013 { 1014 return (a->s6_addr32[0] | a->s6_addr32[1] | 1015 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; 1016 } 1017 #endif 1018 1019 static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) 1020 { 1021 return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); 1022 } 1023 1024 static char *ip4_string(char *p, const u8 *addr) 1025 { 1026 /* 1027 * Since this function is called outside vsnprintf(), I can use 1028 * sprintf() here. 1029 */ 1030 return p + 1031 sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]); 1032 } 1033 1034 static char *ip6_compressed_string(char *p, const char *addr) 1035 { 1036 int i, j, range; 1037 unsigned char zerolength[8]; 1038 int longest = 1; 1039 int colonpos = -1; 1040 u16 word; 1041 u8 hi, lo; 1042 bool needcolon = false; 1043 bool useIPv4; 1044 struct in6_addr in6; 1045 1046 memcpy(&in6, addr, sizeof(struct in6_addr)); 1047 1048 useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); 1049 1050 memset(zerolength, 0, sizeof(zerolength)); 1051 1052 if (useIPv4) 1053 range = 6; 1054 else 1055 range = 8; 1056 1057 /* find position of longest 0 run */ 1058 for (i = 0; i < range; i++) { 1059 for (j = i; j < range; j++) { 1060 if (in6.s6_addr16[j] != 0) 1061 break; 1062 zerolength[i]++; 1063 } 1064 } 1065 for (i = 0; i < range; i++) { 1066 if (zerolength[i] > longest) { 1067 longest = zerolength[i]; 1068 colonpos = i; 1069 } 1070 } 1071 if (longest == 1) /* don't compress a single 0 */ 1072 colonpos = -1; 1073 1074 /* emit address */ 1075 for (i = 0; i < range; i++) { 1076 if (i == colonpos) { 1077 if (needcolon || i == 0) 1078 *p++ = ':'; 1079 *p++ = ':'; 1080 needcolon = false; 1081 i += longest - 1; 1082 continue; 1083 } 1084 if (needcolon) { 1085 *p++ = ':'; 1086 needcolon = false; 1087 } 1088 /* hex u16 without leading 0s */ 1089 word = ntohs(in6.s6_addr16[i]); 1090 hi = word >> 8; 1091 lo = word & 0xff; 1092 if (hi) { 1093 if (hi > 0x0f) 1094 p = pack_hex_byte(p, hi); 1095 else 1096 *p++ = hex_asc_lo(hi); 1097 p = pack_hex_byte(p, lo); 1098 } else if (lo > 0x0f) 1099 p = pack_hex_byte(p, lo); 1100 else 1101 *p++ = hex_asc_lo(lo); 1102 needcolon = true; 1103 } 1104 1105 if (useIPv4) { 1106 if (needcolon) 1107 *p++ = ':'; 1108 p = ip4_string(p, &in6.s6_addr[12]); 1109 } 1110 *p = '\0'; 1111 1112 return p; 1113 } 1114 #endif 1115 1116 /** 1117 * ccs_print_ipv4 - Print an IPv4 address. 1118 * 1119 * @buffer: Buffer to write to. 1120 * @buffer_len: Size of @buffer. 1121 * @ip: Pointer to "u32 in network byte order". 1122 * 1123 * Returns written length. 1124 */ 1125 static int ccs_print_ipv4(char *buffer, const unsigned int buffer_len, 1126 const u32 *ip) 1127 { 1128 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) 1129 return snprintf(buffer, buffer_len, "%pI4", ip); 1130 #else 1131 char addr[sizeof("255.255.255.255")]; 1132 ip4_string(addr, (const u8 *) ip); 1133 return snprintf(buffer, buffer_len, "%s", addr); 1134 #endif 1135 } 1136 1137 /** 1138 * ccs_print_ipv6 - Print an IPv6 address. 1139 * 1140 * @buffer: Buffer to write to. 1141 * @buffer_len: Size of @buffer. 1142 * @ip: Pointer to "struct in6_addr". 1143 * 1144 * Returns written length. 1145 */ 1146 static int ccs_print_ipv6(char *buffer, const unsigned int buffer_len, 1147 const struct in6_addr *ip) 1148 { 1149 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) 1150 return snprintf(buffer, buffer_len, "%pI6c", ip); 1151 #else 1152 char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; 1153 ip6_compressed_string(addr, (const u8 *) ip); 1154 return snprintf(buffer, buffer_len, "%s", addr); 1155 #endif 1156 } 1157 1158 /** 1159 * ccs_print_ip - Print an IP address. 1160 * 1161 * @buf: Buffer to write to. 1162 * @size: Size of @buf. 1163 * @ptr: Pointer to "struct ipaddr_union". 1164 * 1165 * Returns nothing. 1166 */ 1167 static void ccs_print_ip(char *buf, const unsigned int size, 1168 const struct ccs_ipaddr_union *ptr) 1169 { 1170 int len; 1171 if (ptr->is_ipv6) 1172 len = ccs_print_ipv6(buf, size, &ptr->ip[0]); 1173 else 1174 len = ccs_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0]); 1175 if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16) || len >= size / 2) 1176 return; 1177 buf[len++] = '-'; 1178 if (ptr->is_ipv6) 1179 ccs_print_ipv6(buf + len, size - len, &ptr->ip[1]); 1180 else 1181 ccs_print_ipv4(buf + len, size - len, 1182 &ptr->ip[1].s6_addr32[0]); 1183 } 1184 1185 #endif 1186 1187 /***** SECTION5: Variables definition section *****/ 1188 1189 /* Permit policy management by non-root user? */ 1190 static bool ccs_manage_by_non_root; 1191 1192 /* Lock for protecting policy. */ 1193 DEFINE_MUTEX(ccs_policy_lock); 1194 1195 /* Has /sbin/init started? */ 1196 bool ccs_policy_loaded; 1197 1198 /* List of namespaces. */ 1199 LIST_HEAD(ccs_namespace_list); 1200 /* True if namespace other than ccs_kernel_namespace is defined. */ 1201 static bool ccs_namespace_enabled; 1202 1203 /* Initial namespace.*/ 1204 static struct ccs_policy_namespace ccs_kernel_namespace; 1205 1206 /* List of "struct ccs_condition". */ 1207 LIST_HEAD(ccs_condition_list); 1208 1209 #ifdef CONFIG_CCSECURITY_PORTRESERVE 1210 /* Bitmap for reserved local port numbers.*/ 1211 static u8 ccs_reserved_port_map[8192]; 1212 #endif 1213 1214 /* Wait queue for kernel -> userspace notification. */ 1215 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait); 1216 /* Wait queue for userspace -> kernel notification. */ 1217 static DECLARE_WAIT_QUEUE_HEAD(ccs_answer_wait); 1218 1219 /* The list for "struct ccs_query". */ 1220 static LIST_HEAD(ccs_query_list); 1221 1222 /* Lock for manipulating ccs_query_list. */ 1223 static DEFINE_SPINLOCK(ccs_query_list_lock); 1224 1225 /* Number of "struct file" referring /proc/ccs/query interface. */ 1226 static atomic_t ccs_query_observers = ATOMIC_INIT(0); 1227 1228 /* Wait queue for /proc/ccs/audit. */ 1229 static DECLARE_WAIT_QUEUE_HEAD(ccs_log_wait); 1230 1231 /* The list for "struct ccs_log". */ 1232 static LIST_HEAD(ccs_log); 1233 1234 /* Lock for "struct list_head ccs_log". */ 1235 static DEFINE_SPINLOCK(ccs_log_lock); 1236 1237 /* Length of "stuct list_head ccs_log". */ 1238 static unsigned int ccs_log_count; 1239 1240 /* Timestamp counter for last updated. */ 1241 static unsigned int ccs_stat_updated[CCS_MAX_POLICY_STAT]; 1242 1243 /* Counter for number of updates. */ 1244 static unsigned int ccs_stat_modified[CCS_MAX_POLICY_STAT]; 1245 1246 /* Operations for /proc/ccs/self_domain interface. */ 1247 static 1248 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) 1249 const 1250 #endif 1251 struct file_operations ccs_self_operations = { 1252 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 1253 .write = ccs_write_self, 1254 #endif 1255 .read = ccs_read_self, 1256 }; 1257 1258 /* Operations for /proc/ccs/ interface. */ 1259 static 1260 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) 1261 const 1262 #endif 1263 struct file_operations ccs_operations = { 1264 .open = ccs_open, 1265 .release = ccs_release, 1266 .poll = ccs_poll, 1267 .read = ccs_read, 1268 .write = ccs_write, 1269 }; 1270 1271 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) 1272 1273 /* The inode operations for /proc/ccs/ directory. */ 1274 static struct inode_operations ccs_dir_inode_operations; 1275 1276 /* The inode operations for files under /proc/ccs/ directory. */ 1277 static struct inode_operations ccs_file_inode_operations; 1278 1279 #endif 1280 1281 /***** SECTION6: Dependent functions section *****/ 1282 1283 /** 1284 * list_for_each_cookie - iterate over a list with cookie. 1285 * 1286 * @pos: Pointer to "struct list_head". 1287 * @head: Pointer to "struct list_head". 1288 */ 1289 #define list_for_each_cookie(pos, head) \ 1290 for (pos = pos ? pos : srcu_dereference((head)->next, &ccs_ss); \ 1291 pos != (head); pos = srcu_dereference(pos->next, &ccs_ss)) 1292 1293 /** 1294 * ccs_read_token - Read a word from a line. 1295 * 1296 * @param: Pointer to "struct ccs_acl_param". 1297 * 1298 * Returns a word on success, "" otherwise. 1299 * 1300 * To allow the caller to skip NULL check, this function returns "" rather than 1301 * NULL if there is no more words to read. 1302 */ 1303 static char *ccs_read_token(struct ccs_acl_param *param) 1304 { 1305 char *pos = param->data; 1306 char *del = strchr(pos, ' '); 1307 if (del) 1308 *del++ = '\0'; 1309 else 1310 del = pos + strlen(pos); 1311 param->data = del; 1312 return pos; 1313 } 1314 1315 /** 1316 * ccs_make_byte - Make byte value from three octal characters. 1317 * 1318 * @c1: The first character. 1319 * @c2: The second character. 1320 * @c3: The third character. 1321 * 1322 * Returns byte value. 1323 */ 1324 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3) 1325 { 1326 return ((c1 - '') << 6) + ((c2 - '') << 3) + (c3 - ''); 1327 } 1328 1329 /** 1330 * ccs_correct_word2 - Check whether the given string follows the naming rules. 1331 * 1332 * @string: The byte sequence to check. Not '\0'-terminated. 1333 * @len: Length of @string. 1334 * 1335 * Returns true if @string follows the naming rules, false otherwise. 1336 */ 1337 static bool ccs_correct_word2(const char *string, size_t len) 1338 { 1339 u8 recursion = 20; 1340 const char *const start = string; 1341 bool in_repetition = false; 1342 if (!len) 1343 goto out; 1344 while (len--) { 1345 unsigned char c = *string++; 1346 if (c == '\\') { 1347 if (!len--) 1348 goto out; 1349 c = *string++; 1350 if (c >= '' && c <= '3') { 1351 unsigned char d; 1352 unsigned char e; 1353 if (!len-- || !len--) 1354 goto out; 1355 d = *string++; 1356 e = *string++; 1357 if (d < '' || d > '7' || e < '' || e > '7') 1358 goto out; 1359 c = ccs_make_byte(c, d, e); 1360 if (c <= ' ' || c >= 127) 1361 continue; 1362 goto out; 1363 } 1364 switch (c) { 1365 case '\\': /* "\\" */ 1366 case '+': /* "\+" */ 1367 case '?': /* "\?" */ 1368 case 'x': /* "\x" */ 1369 case 'a': /* "\a" */ 1370 case '-': /* "\-" */ 1371 continue; 1372 } 1373 if (!recursion--) 1374 goto out; 1375 switch (c) { 1376 case '*': /* "\*" */ 1377 case '@': /* "\@" */ 1378 case '$': /* "\$" */ 1379 case 'X': /* "\X" */ 1380 case 'A': /* "\A" */ 1381 continue; 1382 case '{': /* "/\{" */ 1383 if (string - 3 < start || *(string - 3) != '/') 1384 goto out; 1385 in_repetition = true; 1386 continue; 1387 case '}': /* "\}/" */ 1388 if (*string != '/') 1389 goto out; 1390 if (!in_repetition) 1391 goto out; 1392 in_repetition = false; 1393 continue; 1394 } 1395 goto out; 1396 } else if (in_repetition && c == '/') { 1397 goto out; 1398 } else if (c <= ' ' || c >= 127) { 1399 goto out; 1400 } 1401 } 1402 if (in_repetition) 1403 goto out; 1404 return true; 1405 out: 1406 return false; 1407 } 1408 1409 /** 1410 * ccs_correct_word - Check whether the given string follows the naming rules. 1411 * 1412 * @string: The string to check. 1413 * 1414 * Returns true if @string follows the naming rules, false otherwise. 1415 */ 1416 static bool ccs_correct_word(const char *string) 1417 { 1418 return ccs_correct_word2(string, strlen(string)); 1419 } 1420 1421 /** 1422 * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group". 1423 * 1424 * @param: Pointer to "struct ccs_acl_param". 1425 * @idx: Index number. 1426 * 1427 * Returns pointer to "struct ccs_group" on success, NULL otherwise. 1428 */ 1429 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param, 1430 const u8 idx) 1431 { 1432 struct ccs_group e = { }; 1433 struct ccs_group *group = NULL; 1434 struct list_head *list; 1435 const char *group_name = ccs_read_token(param); 1436 bool found = false; 1437 if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP) 1438 return NULL; 1439 e.group_name = ccs_get_name(group_name); 1440 if (!e.group_name) 1441 return NULL; 1442 if (mutex_lock_interruptible(&ccs_policy_lock)) 1443 goto out; 1444 list = ¶m->ns->group_list[idx]; 1445 list_for_each_entry(group, list, head.list) { 1446 if (e.group_name != group->group_name || 1447 atomic_read(&group->head.users) == CCS_GC_IN_PROGRESS) 1448 continue; 1449 atomic_inc(&group->head.users); 1450 found = true; 1451 break; 1452 } 1453 if (!found) { 1454 struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e)); 1455 if (entry) { 1456 INIT_LIST_HEAD(&entry->member_list); 1457 atomic_set(&entry->head.users, 1); 1458 list_add_tail_rcu(&entry->head.list, list); 1459 group = entry; 1460 found = true; 1461 } 1462 } 1463 mutex_unlock(&ccs_policy_lock); 1464 out: 1465 ccs_put_name(e.group_name); 1466 return found ? group : NULL; 1467 } 1468 1469 /** 1470 * ccs_parse_name_union - Parse a ccs_name_union. 1471 * 1472 * @param: Pointer to "struct ccs_acl_param". 1473 * @ptr: Pointer to "struct ccs_name_union". 1474 * 1475 * Returns true on success, false otherwise. 1476 */ 1477 static bool ccs_parse_name_union(struct ccs_acl_param *param, 1478 struct ccs_name_union *ptr) 1479 { 1480 char *filename; 1481 if (param->data[0] == '@') { 1482 param->data++; 1483 ptr->group = ccs_get_group(param, CCS_PATH_GROUP); 1484 return ptr->group != NULL; 1485 } 1486 filename = ccs_read_token(param); 1487 if (!ccs_correct_word(filename)) 1488 return false; 1489 ptr->filename = ccs_get_name(filename); 1490 return ptr->filename != NULL; 1491 } 1492 1493 /** 1494 * ccs_parse_ulong - Parse an "unsigned long" value. 1495 * 1496 * @result: Pointer to "unsigned long". 1497 * @str: Pointer to string to parse. 1498 * 1499 * Returns one of values in "enum ccs_value_type". 1500 * 1501 * The @src is updated to point the first character after the value 1502 * on success. 1503 */ 1504 static u8 ccs_parse_ulong(unsigned long *result, char **str) 1505 { 1506 const char *cp = *str; 1507 char *ep; 1508 int base = 10; 1509 if (*cp == '') { 1510 char c = *(cp + 1); 1511 if (c == 'x' || c == 'X') { 1512 base = 16; 1513 cp += 2; 1514 } else if (c >= '' && c <= '7') { 1515 base = 8; 1516 cp++; 1517 } 1518 } 1519 *result = simple_strtoul(cp, &ep, base); 1520 if (cp == ep) 1521 return CCS_VALUE_TYPE_INVALID; 1522 *str = ep; 1523 switch (base) { 1524 case 16: 1525 return CCS_VALUE_TYPE_HEXADECIMAL; 1526 case 8: 1527 return CCS_VALUE_TYPE_OCTAL; 1528 default: 1529 return CCS_VALUE_TYPE_DECIMAL; 1530 } 1531 } 1532 1533 /** 1534 * ccs_parse_number_union - Parse a ccs_number_union. 1535 * 1536 * @param: Pointer to "struct ccs_acl_param". 1537 * @ptr: Pointer to "struct ccs_number_union". 1538 * 1539 * Returns true on success, false otherwise. 1540 */ 1541 static bool ccs_parse_number_union(struct ccs_acl_param *param, 1542 struct ccs_number_union *ptr) 1543 { 1544 char *data; 1545 u8 type; 1546 unsigned long v; 1547 memset(ptr, 0, sizeof(*ptr)); 1548 if (param->data[0] == '@') { 1549 param->data++; 1550 ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP); 1551 return ptr->group != NULL; 1552 } 1553 data = ccs_read_token(param); 1554 type = ccs_parse_ulong(&v, &data); 1555 if (type == CCS_VALUE_TYPE_INVALID) 1556 return false; 1557 ptr->values[0] = v; 1558 ptr->value_type[0] = type; 1559 if (!*data) { 1560 ptr->values[1] = v; 1561 ptr->value_type[1] = type; 1562 return true; 1563 } 1564 if (*data++ != '-') 1565 return false; 1566 type = ccs_parse_ulong(&v, &data); 1567 if (type == CCS_VALUE_TYPE_INVALID || *data || ptr->values[0] > v) 1568 return false; 1569 ptr->values[1] = v; 1570 ptr->value_type[1] = type; 1571 return true; 1572 } 1573 1574 #ifdef CONFIG_CCSECURITY_NETWORK 1575 1576 /** 1577 * ccs_parse_ipaddr_union - Parse an IP address. 1578 * 1579 * @param: Pointer to "struct ccs_acl_param". 1580 * @ptr: Pointer to "struct ccs_ipaddr_union". 1581 * 1582 * Returns true on success, false otherwise. 1583 */ 1584 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param, 1585 struct ccs_ipaddr_union *ptr) 1586 { 1587 u8 * const min = ptr->ip[0].in6_u.u6_addr8; 1588 u8 * const max = ptr->ip[1].in6_u.u6_addr8; 1589 char *address = ccs_read_token(param); 1590 const char *end; 1591 if (!strchr(address, ':') && 1592 ccs_in4_pton(address, -1, min, '-', &end) > 0) { 1593 ptr->is_ipv6 = false; 1594 if (!*end) 1595 ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0]; 1596 else if (*end++ != '-' || 1597 ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end) 1598 return false; 1599 return true; 1600 } 1601 if (ccs_in6_pton(address, -1, min, '-', &end) > 0) { 1602 ptr->is_ipv6 = true; 1603 if (!*end) 1604 memmove(max, min, sizeof(u16) * 8); 1605 else if (*end++ != '-' || 1606 ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end) 1607 return false; 1608 return true; 1609 } 1610 return false; 1611 } 1612 1613 #endif 1614 1615 /** 1616 * ccs_get_dqword - ccs_get_name() for a quoted string. 1617 * 1618 * @start: String to save. 1619 * 1620 * Returns pointer to "struct ccs_path_info" on success, NULL otherwise. 1621 */ 1622 static const struct ccs_path_info *ccs_get_dqword(char *start) 1623 { 1624 char *cp = start + strlen(start) - 1; 1625 if (cp == start || *start++ != '"' || *cp != '"') 1626 return NULL; 1627 *cp = '\0'; 1628 if (*start && !ccs_correct_word(start)) 1629 return NULL; 1630 return ccs_get_name(start); 1631 } 1632 1633 /** 1634 * ccs_parse_name_union_quoted - Parse a quoted word. 1635 * 1636 * @param: Pointer to "struct ccs_acl_param". 1637 * @ptr: Pointer to "struct ccs_name_union". 1638 * 1639 * Returns true on success, false otherwise. 1640 */ 1641 static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param, 1642 struct ccs_name_union *ptr) 1643 { 1644 char *filename = param->data; 1645 if (*filename == '@') 1646 return ccs_parse_name_union(param, ptr); 1647 ptr->filename = ccs_get_dqword(filename); 1648 return ptr->filename != NULL; 1649 } 1650 1651 /** 1652 * ccs_parse_argv - Parse an argv[] condition part. 1653 * 1654 * @left: Lefthand value. 1655 * @right: Righthand value. 1656 * @argv: Pointer to "struct ccs_argv". 1657 * 1658 * Returns true on success, false otherwise. 1659 */ 1660 static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv) 1661 { 1662 if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL || 1663 *left++ != ']' || *left) 1664 return false; 1665 argv->value = ccs_get_dqword(right); 1666 return argv->value != NULL; 1667 } 1668 1669 /** 1670 * ccs_parse_envp - Parse an envp[] condition part. 1671 * 1672 * @left: Lefthand value. 1673 * @right: Righthand value. 1674 * @envp: Pointer to "struct ccs_envp". 1675 * 1676 * Returns true on success, false otherwise. 1677 */ 1678 static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp) 1679 { 1680 const struct ccs_path_info *name; 1681 const struct ccs_path_info *value; 1682 char *cp = left + strlen(left) - 1; 1683 if (*cp-- != ']' || *cp != '"') 1684 goto out; 1685 *cp = '\0'; 1686 if (!ccs_correct_word(left)) 1687 goto out; 1688 name = ccs_get_name(left); 1689 if (!name) 1690 goto out; 1691 if (!strcmp(right, "NULL")) { 1692 value = NULL; 1693 } else { 1694 value = ccs_get_dqword(right); 1695 if (!value) { 1696 ccs_put_name(name); 1697 goto out; 1698 } 1699 } 1700 envp->name = name; 1701 envp->value = value; 1702 return true; 1703 out: 1704 return false; 1705 } 1706 1707 /** 1708 * ccs_same_condition - Check for duplicated "struct ccs_condition" entry. 1709 * 1710 * @a: Pointer to "struct ccs_condition". 1711 * @b: Pointer to "struct ccs_condition". 1712 * 1713 * Returns true if @a == @b, false otherwise. 1714 */ 1715 static bool ccs_same_condition(const struct ccs_condition *a, 1716 const struct ccs_condition *b) 1717 { 1718 return a->size == b->size && a->condc == b->condc && 1719 a->numbers_count == b->numbers_count && 1720 a->names_count == b->names_count && 1721 a->argc == b->argc && a->envc == b->envc && 1722 a->grant_log == b->grant_log && 1723 a->exec_transit == b->exec_transit && a->transit == b->transit 1724 && !memcmp(a + 1, b + 1, a->size - sizeof(*a)); 1725 } 1726 1727 /** 1728 * ccs_condition_type - Get condition type. 1729 * 1730 * @word: Keyword string. 1731 * 1732 * Returns one of values in "enum ccs_conditions_index" on success, 1733 * CCS_MAX_CONDITION_KEYWORD otherwise. 1734 */ 1735 static u8 ccs_condition_type(const char *word) 1736 { 1737 u8 i; 1738 for (i = 0; i < CCS_MAX_CONDITION_KEYWORD; i++) { 1739 if (!strcmp(word, ccs_condition_keyword[i])) 1740 break; 1741 } 1742 return i; 1743 } 1744 1745 /** 1746 * ccs_commit_condition - Commit "struct ccs_condition". 1747 * 1748 * @entry: Pointer to "struct ccs_condition". 1749 * 1750 * Returns pointer to "struct ccs_condition" on success, NULL otherwise. 1751 * 1752 * This function merges duplicated entries. This function returns NULL if 1753 * @entry is not duplicated but memory quota for policy has exceeded. 1754 */ 1755 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry) 1756 { 1757 struct ccs_condition *ptr; 1758 bool found = false; 1759 if (mutex_lock_interruptible(&ccs_policy_lock)) { 1760 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__); 1761 ptr = NULL; 1762 found = true; 1763 goto out; 1764 } 1765 list_for_each_entry(ptr, &ccs_condition_list, head.list) { 1766 if (!ccs_same_condition(ptr, entry) || 1767 atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS) 1768 continue; 1769 /* Same entry found. Share this entry. */ 1770 atomic_inc(&ptr->head.users); 1771 found = true; 1772 break; 1773 } 1774 if (!found) { 1775 if (ccs_memory_ok(entry, entry->size)) { 1776 atomic_set(&entry->head.users, 1); 1777 list_add(&entry->head.list, &ccs_condition_list); 1778 } else { 1779 found = true; 1780 ptr = NULL; 1781 } 1782 } 1783 mutex_unlock(&ccs_policy_lock); 1784 out: 1785 if (found) { 1786 ccs_del_condition(&entry->head.list); 1787 kfree(entry); 1788 entry = ptr; 1789 } 1790 return entry; 1791 } 1792 1793 /** 1794 * ccs_correct_path - Check whether the given pathname follows the naming rules. 1795 * 1796 * @filename: The pathname to check. 1797 * 1798 * Returns true if @filename follows the naming rules, false otherwise. 1799 */ 1800 static bool ccs_correct_path(const char *filename) 1801 { 1802 return *filename == '/' && ccs_correct_word(filename); 1803 } 1804 1805 /** 1806 * ccs_domain_def - Check whether the given token can be a domainname. 1807 * 1808 * @buffer: The token to check. 1809 * 1810 * Returns true if @buffer possibly be a domainname, false otherwise. 1811 */ 1812 static bool ccs_domain_def(const unsigned char *buffer) 1813 { 1814 const unsigned char *cp; 1815 int len; 1816 if (*buffer != '<') 1817 return false; 1818 cp = strchr(buffer, ' '); 1819 if (!cp) 1820 len = strlen(buffer); 1821 else 1822 len = cp - buffer; 1823 if (buffer[len - 1] != '>' || !ccs_correct_word2(buffer + 1, len - 2)) 1824 return false; 1825 return true; 1826 } 1827 1828 /** 1829 * ccs_correct_domain - Check whether the given domainname follows the naming rules. 1830 * 1831 * @domainname: The domainname to check. 1832 * 1833 * Returns true if @domainname follows the naming rules, false otherwise. 1834 */ 1835 static bool ccs_correct_domain(const unsigned char *domainname) 1836 { 1837 if (!domainname || !ccs_domain_def(domainname)) 1838 return false; 1839 domainname = strchr(domainname, ' '); 1840 if (!domainname++) 1841 return true; 1842 while (1) { 1843 const unsigned char *cp = strchr(domainname, ' '); 1844 if (!cp) 1845 break; 1846 if (*domainname != '/' || 1847 !ccs_correct_word2(domainname, cp - domainname)) 1848 return false; 1849 domainname = cp + 1; 1850 } 1851 return ccs_correct_path(domainname); 1852 } 1853 1854 /** 1855 * ccs_normalize_line - Format string. 1856 * 1857 * @buffer: The line to normalize. 1858 * 1859 * Returns nothing. 1860 * 1861 * Leading and trailing whitespaces are removed. 1862 * Multiple whitespaces are packed into single space. 1863 */ 1864 static void ccs_normalize_line(unsigned char *buffer) 1865 { 1866 unsigned char *sp = buffer; 1867 unsigned char *dp = buffer; 1868 bool first = true; 1869 while (*sp && (*sp <= ' ' || *sp >= 127)) 1870 sp++; 1871 while (*sp) { 1872 if (!first) 1873 *dp++ = ' '; 1874 first = false; 1875 while (*sp > ' ' && *sp < 127) 1876 *dp++ = *sp++; 1877 while (*sp && (*sp <= ' ' || *sp >= 127)) 1878 sp++; 1879 } 1880 *dp = '\0'; 1881 } 1882 1883 /** 1884 * ccs_get_domainname - Read a domainname from a line. 1885 * 1886 * @param: Pointer to "struct ccs_acl_param". 1887 * 1888 * Returns a domainname on success, NULL otherwise. 1889 */ 1890 static const struct ccs_path_info *ccs_get_domainname 1891 (struct ccs_acl_param *param) 1892 { 1893 char *start = param->data; 1894 char *pos = start; 1895 while (*pos) { 1896 if (*pos++ != ' ' || *pos++ == '/') 1897 continue; 1898 pos -= 2; 1899 *pos++ = '\0'; 1900 break; 1901 } 1902 param->data = pos; 1903 if (ccs_correct_domain(start)) 1904 return ccs_get_name(start); 1905 return NULL; 1906 } 1907 1908 /** 1909 * ccs_get_transit_preference - Parse domain transition preference for execve(). 1910 * 1911 * @param: Pointer to "struct ccs_acl_param". 1912 * @e: Pointer to "struct ccs_condition". 1913 * 1914 * Returns the condition string part. 1915 */ 1916 static char *ccs_get_transit_preference(struct ccs_acl_param *param, 1917 struct ccs_condition *e) 1918 { 1919 char * const pos = param->data; 1920 bool flag; 1921 if (*pos == '<') { 1922 e->transit = ccs_get_domainname(param); 1923 goto done; 1924 } 1925 { 1926 char *cp = strchr(pos, ' '); 1927 if (cp) 1928 *cp = '\0'; 1929 flag = ccs_correct_path(pos) || !strcmp(pos, "keep") || 1930 !strcmp(pos, "initialize") || !strcmp(pos, "reset") || 1931 !strcmp(pos, "child") || !strcmp(pos, "parent"); 1932 if (cp) 1933 *cp = ' '; 1934 } 1935 if (!flag) 1936 return pos; 1937 e->transit = ccs_get_name(ccs_read_token(param)); 1938 done: 1939 if (e->transit) { 1940 e->exec_transit = true; 1941 return param->data; 1942 } 1943 /* 1944 * Return a bad read-only condition string that will let 1945 * ccs_get_condition() return NULL. 1946 */ 1947 return "/"; 1948 } 1949 1950 /** 1951 * ccs_get_condition - Parse condition part. 1952 * 1953 * @param: Pointer to "struct ccs_acl_param". 1954 * 1955 * Returns pointer to "struct ccs_condition" on success, NULL otherwise. 1956 */ 1957 static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param) 1958 { 1959 struct ccs_condition *entry = NULL; 1960 struct ccs_condition_element *condp = NULL; 1961 struct ccs_number_union *numbers_p = NULL; 1962 struct ccs_name_union *names_p = NULL; 1963 struct ccs_argv *argv = NULL; 1964 struct ccs_envp *envp = NULL; 1965 struct ccs_condition e = { }; 1966 char * const start_of_string = ccs_get_transit_preference(param, &e); 1967 char * const end_of_string = start_of_string + strlen(start_of_string); 1968 char *pos; 1969 rerun: 1970 pos = start_of_string; 1971 while (1) { 1972 u8 left = -1; 1973 u8 right = -1; 1974 char *left_word = pos; 1975 char *cp; 1976 char *right_word; 1977 bool is_not; 1978 if (!*left_word) 1979 break; 1980 /* 1981 * Since left-hand condition does not allow use of "path_group" 1982 * or "number_group" and environment variable's names do not 1983 * accept '=', it is guaranteed that the original line consists 1984 * of one or more repetition of $left$operator$right blocks 1985 * where "$left is free from '=' and ' '" and "$operator is 1986 * either '=' or '!='" and "$right is free from ' '". 1987 * Therefore, we can reconstruct the original line at the end 1988 * of dry run even if we overwrite $operator with '\0'. 1989 */ 1990 cp = strchr(pos, ' '); 1991 if (cp) { 1992 *cp = '\0'; /* Will restore later. */ 1993 pos = cp + 1; 1994 } else { 1995 pos = ""; 1996 } 1997 right_word = strchr(left_word, '='); 1998 if (!right_word || right_word == left_word) 1999 goto out; 2000 is_not = *(right_word - 1) == '!'; 2001 if (is_not) 2002 *(right_word++ - 1) = '\0'; /* Will restore later. */ 2003 else if (*(right_word + 1) != '=') 2004 *right_word++ = '\0'; /* Will restore later. */ 2005 else 2006 goto out; 2007 dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word, 2008 is_not ? "!" : "", right_word); 2009 if (!strcmp(left_word, "grant_log")) { 2010 if (entry) { 2011 if (is_not || 2012 entry->grant_log != CCS_GRANTLOG_AUTO) 2013 goto out; 2014 else if (!strcmp(right_word, "yes")) 2015 entry->grant_log = CCS_GRANTLOG_YES; 2016 else if (!strcmp(right_word, "no")) 2017 entry->grant_log = CCS_GRANTLOG_NO; 2018 else 2019 goto out; 2020 } 2021 continue; 2022 } 2023 if (!strcmp(left_word, "auto_domain_transition")) { 2024 if (entry) { 2025 if (is_not || entry->transit) 2026 goto out; 2027 entry->transit = ccs_get_dqword(right_word); 2028 if (!entry->transit || 2029 (entry->transit->name[0] != '/' && 2030 !ccs_domain_def(entry->transit->name))) 2031 goto out; 2032 } 2033 continue; 2034 } 2035 if (!strncmp(left_word, "exec.argv[", 10)) { 2036 if (!argv) { 2037 e.argc++; 2038 e.condc++; 2039 } else { 2040 e.argc--; 2041 e.condc--; 2042 left = CCS_ARGV_ENTRY; 2043 argv->is_not = is_not; 2044 if (!ccs_parse_argv(left_word + 10, 2045 right_word, argv++)) 2046 goto out; 2047 } 2048 goto store_value; 2049 } 2050 if (!strncmp(left_word, "exec.envp[\"", 11)) { 2051 if (!envp) { 2052 e.envc++; 2053 e.condc++; 2054 } else { 2055 e.envc--; 2056 e.condc--; 2057 left = CCS_ENVP_ENTRY; 2058 envp->is_not = is_not; 2059 if (!ccs_parse_envp(left_word + 11, 2060 right_word, envp++)) 2061 goto out; 2062 } 2063 goto store_value; 2064 } 2065 left = ccs_condition_type(left_word); 2066 dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word, 2067 left); 2068 if (left == CCS_MAX_CONDITION_KEYWORD) { 2069 if (!numbers_p) { 2070 e.numbers_count++; 2071 } else { 2072 e.numbers_count--; 2073 left = CCS_NUMBER_UNION; 2074 param->data = left_word; 2075 if (*left_word == '@' || 2076 !ccs_parse_number_union(param, 2077 numbers_p++)) 2078 goto out; 2079 } 2080 } 2081 if (!condp) 2082 e.condc++; 2083 else 2084 e.condc--; 2085 if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) { 2086 if (!names_p) { 2087 e.names_count++; 2088 } else { 2089 e.names_count--; 2090 right = CCS_NAME_UNION; 2091 param->data = right_word; 2092 if (!ccs_parse_name_union_quoted(param, 2093 names_p++)) 2094 goto out; 2095 } 2096 goto store_value; 2097 } 2098 right = ccs_condition_type(right_word); 2099 if (right == CCS_MAX_CONDITION_KEYWORD) { 2100 if (!numbers_p) { 2101 e.numbers_count++; 2102 } else { 2103 e.numbers_count--; 2104 right = CCS_NUMBER_UNION; 2105 param->data = right_word; 2106 if (!ccs_parse_number_union(param, 2107 numbers_p++)) 2108 goto out; 2109 } 2110 } 2111 store_value: 2112 if (!condp) { 2113 dprintk(KERN_WARNING "%u: dry_run left=%u right=%u " 2114 "match=%u\n", __LINE__, left, right, !is_not); 2115 continue; 2116 } 2117 condp->left = left; 2118 condp->right = right; 2119 condp->equals = !is_not; 2120 dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n", 2121 __LINE__, condp->left, condp->right, 2122 condp->equals); 2123 condp++; 2124 } 2125 dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n", 2126 __LINE__, e.condc, e.numbers_count, e.names_count, e.argc, 2127 e.envc); 2128 if (entry) { 2129 BUG_ON(e.names_count | e.numbers_count | e.argc | e.envc | 2130 e.condc); 2131 return ccs_commit_condition(entry); 2132 } 2133 e.size = sizeof(*entry) 2134 + e.condc * sizeof(struct ccs_condition_element) 2135 + e.numbers_count * sizeof(struct ccs_number_union) 2136 + e.names_count * sizeof(struct ccs_name_union) 2137 + e.argc * sizeof(struct ccs_argv) 2138 + e.envc * sizeof(struct ccs_envp); 2139 entry = kzalloc(e.size, CCS_GFP_FLAGS); 2140 if (!entry) 2141 goto out2; 2142 *entry = e; 2143 e.transit = NULL; 2144 condp = (struct ccs_condition_element *) (entry + 1); 2145 numbers_p = (struct ccs_number_union *) (condp + e.condc); 2146 names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count); 2147 argv = (struct ccs_argv *) (names_p + e.names_count); 2148 envp = (struct ccs_envp *) (argv + e.argc); 2149 { 2150 bool flag = false; 2151 for (pos = start_of_string; pos < end_of_string; pos++) { 2152 if (*pos) 2153 continue; 2154 if (flag) /* Restore " ". */ 2155 *pos = ' '; 2156 else if (*(pos + 1) == '=') /* Restore "!=". */ 2157 *pos = '!'; 2158 else /* Restore "=". */ 2159 *pos = '='; 2160 flag = !flag; 2161 } 2162 } 2163 goto rerun; 2164 out: 2165 dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__); 2166 if (entry) { 2167 ccs_del_condition(&entry->head.list); 2168 kfree(entry); 2169 } 2170 out2: 2171 ccs_put_name(e.transit); 2172 return NULL; 2173 } 2174 2175 /** 2176 * ccs_yesno - Return "yes" or "no". 2177 * 2178 * @value: Bool value. 2179 * 2180 * Returns "yes" if @value is not 0, "no" otherwise. 2181 */ 2182 static const char *ccs_yesno(const unsigned int value) 2183 { 2184 return value ? "yes" : "no"; 2185 } 2186 2187 /** 2188 * ccs_addprintf - strncat()-like-snprintf(). 2189 * 2190 * @buffer: Buffer to write to. Must be '\0'-terminated. 2191 * @len: Size of @buffer. 2192 * @fmt: The printf()'s format string, followed by parameters. 2193 * 2194 * Returns nothing. 2195 */ 2196 static void ccs_addprintf(char *buffer, int len, const char *fmt, ...) 2197 { 2198 va_list args; 2199 const int pos = strlen(buffer); 2200 va_start(args, fmt); 2201 vsnprintf(buffer + pos, len - pos - 1, fmt, args); 2202 va_end(args); 2203 } 2204 2205 /** 2206 * ccs_flush - Flush queued string to userspace's buffer. 2207 * 2208 * @head: Pointer to "struct ccs_io_buffer". 2209 * 2210 * Returns true if all data was flushed, false otherwise. 2211 */ 2212 static bool ccs_flush(struct ccs_io_buffer *head) 2213 { 2214 while (head->r.w_pos) { 2215 const char *w = head->r.w[0]; 2216 size_t len = strlen(w); 2217 if (len) { 2218 if (len > head->read_user_buf_avail) 2219 len = head->read_user_buf_avail; 2220 if (!len) 2221 return false; 2222 if (copy_to_user(head->read_user_buf, w, len)) 2223 return false; 2224 head->read_user_buf_avail -= len; 2225 head->read_user_buf += len; 2226 w += len; 2227 } 2228 head->r.w[0] = w; 2229 if (*w) 2230 return false; 2231 /* Add '\0' for audit logs and query. */ 2232 if (head->type == CCS_AUDIT || head->type == CCS_QUERY) { 2233 if (!head->read_user_buf_avail || 2234 copy_to_user(head->read_user_buf, "", 1)) 2235 return false; 2236 head->read_user_buf_avail--; 2237 head->read_user_buf++; 2238 } 2239 head->r.w_pos--; 2240 for (len = 0; len < head->r.w_pos; len++) 2241 head->r.w[len] = head->r.w[len + 1]; 2242 } 2243 head->r.avail = 0; 2244 return true; 2245 } 2246 2247 /** 2248 * ccs_set_string - Queue string to "struct ccs_io_buffer" structure. 2249 * 2250 * @head: Pointer to "struct ccs_io_buffer". 2251 * @string: String to print. 2252 * 2253 * Returns nothing. 2254 * 2255 * Note that @string has to be kept valid until @head is kfree()d. 2256 * This means that char[] allocated on stack memory cannot be passed to 2257 * this function. Use ccs_io_printf() for char[] allocated on stack memory. 2258 */ 2259 static void ccs_set_string(struct ccs_io_buffer *head, const char *string) 2260 { 2261 if (head->r.w_pos < CCS_MAX_IO_READ_QUEUE) { 2262 head->r.w[head->r.w_pos++] = string; 2263 ccs_flush(head); 2264 } else 2265 printk(KERN_WARNING "Too many words in a line.\n"); 2266 } 2267 2268 /** 2269 * ccs_io_printf - printf() to "struct ccs_io_buffer" structure. 2270 * 2271 * @head: Pointer to "struct ccs_io_buffer". 2272 * @fmt: The printf()'s format string, followed by parameters. 2273 * 2274 * Returns nothing. 2275 */ 2276 static void ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...) 2277 { 2278 va_list args; 2279 size_t len; 2280 size_t pos = head->r.avail; 2281 int size = head->readbuf_size - pos; 2282 if (size <= 0) 2283 return; 2284 va_start(args, fmt); 2285 len = vsnprintf(head->read_buf + pos, size, fmt, args) + 1; 2286 va_end(args); 2287 if (pos + len >= head->readbuf_size) { 2288 printk(KERN_WARNING "Too many words in a line.\n"); 2289 return; 2290 } 2291 head->r.avail += len; 2292 ccs_set_string(head, head->read_buf + pos); 2293 } 2294 2295 /** 2296 * ccs_set_space - Put a space to "struct ccs_io_buffer" structure. 2297 * 2298 * @head: Pointer to "struct ccs_io_buffer". 2299 * 2300 * Returns nothing. 2301 */ 2302 static void ccs_set_space(struct ccs_io_buffer *head) 2303 { 2304 ccs_set_string(head, " "); 2305 } 2306 2307 /** 2308 * ccs_set_lf - Put a line feed to "struct ccs_io_buffer" structure. 2309 * 2310 * @head: Pointer to "struct ccs_io_buffer". 2311 * 2312 * Returns true if all data was flushed, false otherwise. 2313 */ 2314 static bool ccs_set_lf(struct ccs_io_buffer *head) 2315 { 2316 ccs_set_string(head, "\n"); 2317 return !head->r.w_pos; 2318 } 2319 2320 /** 2321 * ccs_set_slash - Put a shash to "struct ccs_io_buffer" structure. 2322 * 2323 * @head: Pointer to "struct ccs_io_buffer". 2324 * 2325 * Returns nothing. 2326 */ 2327 static void ccs_set_slash(struct ccs_io_buffer *head) 2328 { 2329 ccs_set_string(head, "/"); 2330 } 2331 2332 /** 2333 * ccs_init_policy_namespace - Initialize namespace. 2334 * 2335 * @ns: Pointer to "struct ccs_policy_namespace". 2336 * 2337 * Returns nothing. 2338 */ 2339 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns) 2340 { 2341 unsigned int idx; 2342 for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++) 2343 INIT_LIST_HEAD(&ns->acl_group[idx]); 2344 for (idx = 0; idx < CCS_MAX_GROUP; idx++) 2345 INIT_LIST_HEAD(&ns->group_list[idx]); 2346 for (idx = 0; idx < CCS_MAX_POLICY; idx++) 2347 INIT_LIST_HEAD(&ns->policy_list[idx]); 2348 ns->profile_version = 20150505; 2349 ccs_namespace_enabled = !list_empty(&ccs_namespace_list); 2350 list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list); 2351 } 2352 2353 /** 2354 * ccs_print_namespace - Print namespace header. 2355 * 2356 * @head: Pointer to "struct ccs_io_buffer". 2357 * 2358 * Returns nothing. 2359 */ 2360 static void ccs_print_namespace(struct ccs_io_buffer *head) 2361 { 2362 if (!ccs_namespace_enabled) 2363 return; 2364 ccs_set_string(head, 2365 container_of(head->r.ns, struct ccs_policy_namespace, 2366 namespace_list)->name); 2367 ccs_set_space(head); 2368 } 2369 2370 /** 2371 * ccs_assign_profile - Create a new profile. 2372 * 2373 * @ns: Pointer to "struct ccs_policy_namespace". 2374 * @profile: Profile number to create. 2375 * 2376 * Returns pointer to "struct ccs_profile" on success, NULL otherwise. 2377 */ 2378 static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns, 2379 const unsigned int profile) 2380 { 2381 struct ccs_profile *ptr; 2382 struct ccs_profile *entry; 2383 if (profile >= CCS_MAX_PROFILES) 2384 return NULL; 2385 ptr = ns->profile_ptr[profile]; 2386 if (ptr) 2387 return ptr; 2388 entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS); 2389 if (mutex_lock_interruptible(&ccs_policy_lock)) 2390 goto out; 2391 ptr = ns->profile_ptr[profile]; 2392 if (!ptr && ccs_memory_ok(entry, sizeof(*entry))) { 2393 ptr = entry; 2394 ptr->default_config = CCS_CONFIG_DISABLED | 2395 CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG; 2396 memset(ptr->config, CCS_CONFIG_USE_DEFAULT, 2397 sizeof(ptr->config)); 2398 ptr->pref[CCS_PREF_MAX_AUDIT_LOG] = 2399 CONFIG_CCSECURITY_MAX_AUDIT_LOG; 2400 ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] = 2401 CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY; 2402 mb(); /* Avoid out-of-order execution. */ 2403 ns->profile_ptr[profile] = ptr; 2404 entry = NULL; 2405 } 2406 mutex_unlock(&ccs_policy_lock); 2407 out: 2408 kfree(entry); 2409 return ptr; 2410 } 2411 2412 /** 2413 * ccs_check_profile - Check all profiles currently assigned to domains are defined. 2414 * 2415 * Returns nothing. 2416 */ 2417 static void ccs_check_profile(void) 2418 { 2419 struct ccs_domain_info *domain; 2420 const int idx = ccs_read_lock(); 2421 ccs_policy_loaded = true; 2422 printk(KERN_INFO "CCSecurity: 1.8.5+ 2018/04/01\n"); 2423 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 2424 const u8 profile = domain->profile; 2425 struct ccs_policy_namespace *ns = domain->ns; 2426 if (ns->profile_version == 20100903) { 2427 static bool done; 2428 if (!done) 2429 printk(KERN_INFO "Converting profile version " 2430 "from %u to %u.\n", 20100903, 20150505); 2431 done = true; 2432 ns->profile_version = 20150505; 2433 } 2434 if (ns->profile_version != 20150505) 2435 printk(KERN_ERR 2436 "Profile version %u is not supported.\n", 2437 ns->profile_version); 2438 else if (!ns->profile_ptr[profile]) 2439 printk(KERN_ERR 2440 "Profile %u (used by '%s') is not defined.\n", 2441 profile, domain->domainname->name); 2442 else 2443 continue; 2444 printk(KERN_ERR 2445 "Userland tools for TOMOYO 1.8 must be installed and " 2446 "policy must be initialized.\n"); 2447 printk(KERN_ERR "Please see http://tomoyo.osdn.jp/1.8/ " 2448 "for more information.\n"); 2449 panic("STOP!"); 2450 } 2451 ccs_read_unlock(idx); 2452 printk(KERN_INFO "Mandatory Access Control activated.\n"); 2453 } 2454 2455 /** 2456 * ccs_profile - Find a profile. 2457 * 2458 * @profile: Profile number to find. 2459 * 2460 * Returns pointer to "struct ccs_profile". 2461 */ 2462 static struct ccs_profile *ccs_profile(const u8 profile) 2463 { 2464 static struct ccs_profile ccs_null_profile; 2465 struct ccs_profile *ptr = ccs_current_namespace()-> 2466 profile_ptr[profile]; 2467 if (!ptr) 2468 ptr = &ccs_null_profile; 2469 return ptr; 2470 } 2471 2472 /** 2473 * ccs_get_config - Get config for specified profile's specified functionality. 2474 * 2475 * @profile: Profile number. 2476 * @index: Index number of functionality. 2477 * 2478 * Returns config. 2479 * 2480 * First, check for CONFIG::category::functionality. 2481 * If CONFIG::category::functionality is set to use default, then check 2482 * CONFIG::category. If CONFIG::category is set to use default, then use 2483 * CONFIG. CONFIG cannot be set to use default. 2484 */ 2485 u8 ccs_get_config(const u8 profile, const u8 index) 2486 { 2487 u8 config; 2488 const struct ccs_profile *p; 2489 if (!ccs_policy_loaded) 2490 return CCS_CONFIG_DISABLED; 2491 p = ccs_profile(profile); 2492 config = p->config[index]; 2493 if (config == CCS_CONFIG_USE_DEFAULT) 2494 config = p->config[ccs_index2category[index] 2495 + CCS_MAX_MAC_INDEX]; 2496 if (config == CCS_CONFIG_USE_DEFAULT) 2497 config = p->default_config; 2498 return config; 2499 } 2500 2501 /** 2502 * ccs_find_yesno - Find values for specified keyword. 2503 * 2504 * @string: String to check. 2505 * @find: Name of keyword. 2506 * 2507 * Returns 1 if "@find=yes" was found, 0 if "@find=no" was found, -1 otherwise. 2508 */ 2509 static s8 ccs_find_yesno(const char *string, const char *find) 2510 { 2511 const char *cp = strstr(string, find); 2512 if (cp) { 2513 cp += strlen(find); 2514 if (!strncmp(cp, "=yes", 4)) 2515 return 1; 2516 else if (!strncmp(cp, "=no", 3)) 2517 return 0; 2518 } 2519 return -1; 2520 } 2521 2522 /** 2523 * ccs_set_uint - Set value for specified preference. 2524 * 2525 * @i: Pointer to "unsigned int". 2526 * @string: String to check. 2527 * @find: Name of keyword. 2528 * 2529 * Returns nothing. 2530 */ 2531 static void ccs_set_uint(unsigned int *i, const char *string, const char *find) 2532 { 2533 const char *cp = strstr(string, find); 2534 if (cp) 2535 sscanf(cp + strlen(find), "=%u", i); 2536 } 2537 2538 /** 2539 * ccs_str_starts - Check whether the given string starts with the given keyword. 2540 * 2541 * @src: Pointer to pointer to the string. 2542 * @find: Pointer to the keyword. 2543 * 2544 * Returns true if @src starts with @find, false otherwise. 2545 * 2546 * The @src is updated to point the first character after the @find 2547 * if @src starts with @find. 2548 */ 2549 static bool ccs_str_starts(char **src, const char *find) 2550 { 2551 const int len = strlen(find); 2552 char *tmp = *src; 2553 if (strncmp(tmp, find, len)) 2554 return false; 2555 tmp += len; 2556 *src = tmp; 2557 return true; 2558 } 2559 2560 /** 2561 * ccs_print_group - Print group's name. 2562 * 2563 * @head: Pointer to "struct ccs_io_buffer". 2564 * @group: Pointer to "struct ccsgroup". Maybe NULL. 2565 * 2566 * Returns true if @group is not NULL. false otherwise. 2567 */ 2568 static bool ccs_print_group(struct ccs_io_buffer *head, 2569 const struct ccs_group *group) 2570 { 2571 if (group) { 2572 ccs_set_string(head, "@"); 2573 ccs_set_string(head, group->group_name->name); 2574 return true; 2575 } 2576 return false; 2577 } 2578 2579 /** 2580 * ccs_set_mode - Set mode for specified profile. 2581 * 2582 * @name: Name of functionality. 2583 * @value: Mode for @name. 2584 * @profile: Pointer to "struct ccs_profile". 2585 * 2586 * Returns 0 on success, negative value otherwise. 2587 */ 2588 static int ccs_set_mode(char *name, const char *value, 2589 struct ccs_profile *profile) 2590 { 2591 u8 i; 2592 u8 config; 2593 if (!strcmp(name, "CONFIG")) { 2594 i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX; 2595 config = profile->default_config; 2596 } else if (ccs_str_starts(&name, "CONFIG::")) { 2597 config = 0; 2598 for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX; 2599 i++) { 2600 int len = 0; 2601 if (i < CCS_MAX_MAC_INDEX) { 2602 const u8 c = ccs_index2category[i]; 2603 const char *category = 2604 ccs_category_keywords[c]; 2605 len = strlen(category); 2606 if (strncmp(name, category, len) || 2607 name[len++] != ':' || name[len++] != ':') 2608 continue; 2609 } 2610 if (strcmp(name + len, ccs_mac_keywords[i])) 2611 continue; 2612 config = profile->config[i]; 2613 break; 2614 } 2615 if (i == CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX) 2616 return -EINVAL; 2617 } else { 2618 return -EINVAL; 2619 } 2620 if (strstr(value, "use_default")) { 2621 config = CCS_CONFIG_USE_DEFAULT; 2622 } else { 2623 u8 mode; 2624 for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++) 2625 if (strstr(value, ccs_mode[mode])) 2626 /* 2627 * Update lower 3 bits in order to distinguish 2628 * 'config' from 'CCS_CONFIG_USE_DEAFULT'. 2629 */ 2630 config = (config & ~7) | mode; 2631 if (config != CCS_CONFIG_USE_DEFAULT) { 2632 switch (ccs_find_yesno(value, "grant_log")) { 2633 case 1: 2634 config |= CCS_CONFIG_WANT_GRANT_LOG; 2635 break; 2636 case 0: 2637 config &= ~CCS_CONFIG_WANT_GRANT_LOG; 2638 break; 2639 } 2640 switch (ccs_find_yesno(value, "reject_log")) { 2641 case 1: 2642 config |= CCS_CONFIG_WANT_REJECT_LOG; 2643 break; 2644 case 0: 2645 config &= ~CCS_CONFIG_WANT_REJECT_LOG; 2646 break; 2647 } 2648 } 2649 } 2650 if (i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX) 2651 profile->config[i] = config; 2652 else if (config != CCS_CONFIG_USE_DEFAULT) 2653 profile->default_config = config; 2654 return 0; 2655 } 2656 2657 /** 2658 * ccs_write_profile - Write profile table. 2659 * 2660 * @head: Pointer to "struct ccs_io_buffer". 2661 * 2662 * Returns 0 on success, negative value otherwise. 2663 */ 2664 static int ccs_write_profile(struct ccs_io_buffer *head) 2665 { 2666 char *data = head->write_buf; 2667 unsigned int i; 2668 char *cp; 2669 struct ccs_profile *profile; 2670 if (sscanf(data, "PROFILE_VERSION=%u", &head->w.ns->profile_version) 2671 == 1) 2672 return 0; 2673 i = simple_strtoul(data, &cp, 10); 2674 if (*cp != '-') 2675 return -EINVAL; 2676 data = cp + 1; 2677 profile = ccs_assign_profile(head->w.ns, i); 2678 if (!profile) 2679 return -EINVAL; 2680 cp = strchr(data, '='); 2681 if (!cp) 2682 return -EINVAL; 2683 *cp++ = '\0'; 2684 if (!strcmp(data, "COMMENT")) { 2685 static DEFINE_SPINLOCK(lock); 2686 const struct ccs_path_info *new_comment = ccs_get_name(cp); 2687 const struct ccs_path_info *old_comment; 2688 if (!new_comment) 2689 return -ENOMEM; 2690 spin_lock(&lock); 2691 old_comment = profile->comment; 2692 profile->comment = new_comment; 2693 spin_unlock(&lock); 2694 ccs_put_name(old_comment); 2695 return 0; 2696 } 2697 if (!strcmp(data, "PREFERENCE")) { 2698 for (i = 0; i < CCS_MAX_PREF; i++) 2699 ccs_set_uint(&profile->pref[i], cp, 2700 ccs_pref_keywords[i]); 2701 return 0; 2702 } 2703 return ccs_set_mode(data, cp, profile); 2704 } 2705 2706 /** 2707 * ccs_print_config - Print mode for specified functionality. 2708 * 2709 * @head: Pointer to "struct ccs_io_buffer". 2710 * @config: Mode for that functionality. 2711 * 2712 * Returns nothing. 2713 * 2714 * Caller prints functionality's name. 2715 */ 2716 static void ccs_print_config(struct ccs_io_buffer *head, const u8 config) 2717 { 2718 ccs_io_printf(head, "={ mode=%s grant_log=%s reject_log=%s }\n", 2719 ccs_mode[config & 3], 2720 ccs_yesno(config & CCS_CONFIG_WANT_GRANT_LOG), 2721 ccs_yesno(config & CCS_CONFIG_WANT_REJECT_LOG)); 2722 } 2723 2724 /** 2725 * ccs_read_profile - Read profile table. 2726 * 2727 * @head: Pointer to "struct ccs_io_buffer". 2728 * 2729 * Returns nothing. 2730 */ 2731 static void ccs_read_profile(struct ccs_io_buffer *head) 2732 { 2733 u8 index; 2734 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 2735 namespace_list); 2736 const struct ccs_profile *profile; 2737 if (head->r.eof) 2738 return; 2739 next: 2740 index = head->r.index; 2741 profile = ns->profile_ptr[index]; 2742 switch (head->r.step) { 2743 case 0: 2744 ccs_print_namespace(head); 2745 ccs_io_printf(head, "PROFILE_VERSION=%u\n", 2746 ns->profile_version); 2747 head->r.step++; 2748 break; 2749 case 1: 2750 for ( ; head->r.index < CCS_MAX_PROFILES; head->r.index++) 2751 if (ns->profile_ptr[head->r.index]) 2752 break; 2753 if (head->r.index == CCS_MAX_PROFILES) { 2754 head->r.eof = true; 2755 return; 2756 } 2757 head->r.step++; 2758 break; 2759 case 2: 2760 { 2761 u8 i; 2762 const struct ccs_path_info *comment = profile->comment; 2763 ccs_print_namespace(head); 2764 ccs_io_printf(head, "%u-COMMENT=", index); 2765 ccs_set_string(head, comment ? comment->name : ""); 2766 ccs_set_lf(head); 2767 ccs_print_namespace(head); 2768 ccs_io_printf(head, "%u-PREFERENCE={ ", index); 2769 for (i = 0; i < CCS_MAX_PREF; i++) 2770 ccs_io_printf(head, "%s=%u ", 2771 ccs_pref_keywords[i], 2772 profile->pref[i]); 2773 ccs_set_string(head, "}\n"); 2774 head->r.step++; 2775 } 2776 break; 2777 case 3: 2778 { 2779 ccs_print_namespace(head); 2780 ccs_io_printf(head, "%u-%s", index, "CONFIG"); 2781 ccs_print_config(head, profile->default_config); 2782 head->r.bit = 0; 2783 head->r.step++; 2784 } 2785 break; 2786 case 4: 2787 for ( ; head->r.bit < CCS_MAX_MAC_INDEX 2788 + CCS_MAX_MAC_CATEGORY_INDEX; head->r.bit++) { 2789 const u8 i = head->r.bit; 2790 const u8 config = profile->config[i]; 2791 if (config == CCS_CONFIG_USE_DEFAULT) 2792 continue; 2793 ccs_print_namespace(head); 2794 if (i < CCS_MAX_MAC_INDEX) 2795 ccs_io_printf(head, "%u-CONFIG::%s::%s", index, 2796 ccs_category_keywords 2797 [ccs_index2category[i]], 2798 ccs_mac_keywords[i]); 2799 else 2800 ccs_io_printf(head, "%u-CONFIG::%s", index, 2801 ccs_mac_keywords[i]); 2802 ccs_print_config(head, config); 2803 head->r.bit++; 2804 break; 2805 } 2806 if (head->r.bit == CCS_MAX_MAC_INDEX 2807 + CCS_MAX_MAC_CATEGORY_INDEX) { 2808 head->r.index++; 2809 head->r.step = 1; 2810 } 2811 break; 2812 } 2813 if (ccs_flush(head)) 2814 goto next; 2815 } 2816 2817 /** 2818 * ccs_update_policy - Update an entry for exception policy. 2819 * 2820 * @size: Size of new entry in bytes. 2821 * @param: Pointer to "struct ccs_acl_param". 2822 * 2823 * Returns 0 on success, negative value otherwise. 2824 * 2825 * Caller holds ccs_read_lock(). 2826 */ 2827 static int ccs_update_policy(const int size, struct ccs_acl_param *param) 2828 { 2829 struct ccs_acl_head *new_entry = ¶m->e.acl_head; 2830 int error = param->is_delete ? -ENOENT : -ENOMEM; 2831 struct ccs_acl_head *entry; 2832 struct list_head *list = param->list; 2833 BUG_ON(size < sizeof(*entry)); 2834 if (mutex_lock_interruptible(&ccs_policy_lock)) 2835 return -ENOMEM; 2836 list_for_each_entry_srcu(entry, list, list, &ccs_ss) { 2837 if (entry->is_deleted == CCS_GC_IN_PROGRESS) 2838 continue; 2839 if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry))) 2840 continue; 2841 entry->is_deleted = param->is_delete; 2842 error = 0; 2843 break; 2844 } 2845 if (error && !param->is_delete) { 2846 entry = ccs_commit_ok(new_entry, size); 2847 if (entry) { 2848 list_add_tail_rcu(&entry->list, list); 2849 error = 0; 2850 } 2851 } 2852 mutex_unlock(&ccs_policy_lock); 2853 return error; 2854 } 2855 2856 /** 2857 * ccs_update_manager_entry - Add a manager entry. 2858 * 2859 * @manager: The path to manager or the domainnamme. 2860 * @is_delete: True if it is a delete request. 2861 * 2862 * Returns 0 on success, negative value otherwise. 2863 */ 2864 static int ccs_update_manager_entry(const char *manager, 2865 const bool is_delete) 2866 { 2867 struct ccs_acl_param param = { 2868 /* .ns = &ccs_kernel_namespace, */ 2869 .is_delete = is_delete, 2870 .list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER], 2871 }; 2872 struct ccs_manager *e = ¶m.e.manager; 2873 int error = is_delete ? -ENOENT : -ENOMEM; 2874 /* Forced zero clear for using memcmp() at ccs_update_policy(). */ 2875 memset(¶m.e, 0, sizeof(param.e)); 2876 if (!ccs_correct_domain(manager) && !ccs_correct_word(manager)) 2877 return -EINVAL; 2878 e->manager = ccs_get_name(manager); 2879 if (e->manager) { 2880 error = ccs_update_policy(sizeof(*e), ¶m); 2881 ccs_put_name(e->manager); 2882 } 2883 return error; 2884 } 2885 2886 /** 2887 * ccs_write_manager - Write manager policy. 2888 * 2889 * @head: Pointer to "struct ccs_io_buffer". 2890 * 2891 * Returns 0 on success, negative value otherwise. 2892 */ 2893 static int ccs_write_manager(struct ccs_io_buffer *head) 2894 { 2895 const char *data = head->write_buf; 2896 if (!strcmp(data, "manage_by_non_root")) { 2897 ccs_manage_by_non_root = !head->w.is_delete; 2898 return 0; 2899 } 2900 return ccs_update_manager_entry(data, head->w.is_delete); 2901 } 2902 2903 /** 2904 * ccs_read_manager - Read manager policy. 2905 * 2906 * @head: Pointer to "struct ccs_io_buffer". 2907 * 2908 * Returns nothing. 2909 * 2910 * Caller holds ccs_read_lock(). 2911 */ 2912 static void ccs_read_manager(struct ccs_io_buffer *head) 2913 { 2914 if (head->r.eof) 2915 return; 2916 list_for_each_cookie(head->r.acl, &ccs_kernel_namespace. 2917 policy_list[CCS_ID_MANAGER]) { 2918 struct ccs_manager *ptr = 2919 list_entry(head->r.acl, typeof(*ptr), head.list); 2920 if (ptr->head.is_deleted) 2921 continue; 2922 if (!ccs_flush(head)) 2923 return; 2924 ccs_set_string(head, ptr->manager->name); 2925 ccs_set_lf(head); 2926 } 2927 head->r.eof = true; 2928 } 2929 2930 /** 2931 * ccs_manager - Check whether the current process is a policy manager. 2932 * 2933 * Returns true if the current process is permitted to modify policy 2934 * via /proc/ccs/ interface. 2935 * 2936 * Caller holds ccs_read_lock(). 2937 */ 2938 static bool ccs_manager(void) 2939 { 2940 struct ccs_manager *ptr; 2941 struct ccs_path_info exe; 2942 struct ccs_security *task = ccs_current_security(); 2943 const struct ccs_path_info *domainname 2944 = ccs_current_domain()->domainname; 2945 bool found = false; 2946 if (!ccs_policy_loaded) 2947 return true; 2948 if (task->ccs_flags & CCS_TASK_IS_MANAGER) 2949 return true; 2950 if (!ccs_manage_by_non_root && 2951 (!uid_eq(current_uid(), GLOBAL_ROOT_UID) || 2952 !uid_eq(current_euid(), GLOBAL_ROOT_UID))) 2953 return false; 2954 exe.name = ccs_get_exe(); 2955 if (!exe.name) 2956 return false; 2957 ccs_fill_path_info(&exe); 2958 list_for_each_entry_srcu(ptr, &ccs_kernel_namespace. 2959 policy_list[CCS_ID_MANAGER], head.list, 2960 &ccs_ss) { 2961 if (ptr->head.is_deleted) 2962 continue; 2963 if (ccs_pathcmp(domainname, ptr->manager) && 2964 ccs_pathcmp(&exe, ptr->manager)) 2965 continue; 2966 /* Set manager flag. */ 2967 task->ccs_flags |= CCS_TASK_IS_MANAGER; 2968 found = true; 2969 break; 2970 } 2971 if (!found) { /* Reduce error messages. */ 2972 static pid_t ccs_last_pid; 2973 const pid_t pid = current->pid; 2974 if (ccs_last_pid != pid) { 2975 printk(KERN_WARNING "%s ( %s ) is not permitted to " 2976 "update policies.\n", domainname->name, 2977 exe.name); 2978 ccs_last_pid = pid; 2979 } 2980 } 2981 kfree(exe.name); 2982 return found; 2983 } 2984 2985 /** 2986 * ccs_find_domain - Find a domain by the given name. 2987 * 2988 * @domainname: The domainname to find. 2989 * 2990 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise. 2991 * 2992 * Caller holds ccs_read_lock(). 2993 */ 2994 static struct ccs_domain_info *ccs_find_domain(const char *domainname) 2995 { 2996 struct ccs_domain_info *domain; 2997 struct ccs_path_info name; 2998 name.name = domainname; 2999 ccs_fill_path_info(&name); 3000 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 3001 if (!domain->is_deleted && 3002 !ccs_pathcmp(&name, domain->domainname)) 3003 return domain; 3004 } 3005 return NULL; 3006 } 3007 3008 /** 3009 * ccs_select_domain - Parse select command. 3010 * 3011 * @head: Pointer to "struct ccs_io_buffer". 3012 * @data: String to parse. 3013 * 3014 * Returns true on success, false otherwise. 3015 * 3016 * Caller holds ccs_read_lock(). 3017 */ 3018 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data) 3019 { 3020 unsigned int pid; 3021 struct ccs_domain_info *domain = NULL; 3022 bool global_pid = false; 3023 if (strncmp(data, "select ", 7)) 3024 return false; 3025 data += 7; 3026 if (sscanf(data, "pid=%u", &pid) == 1 || 3027 (global_pid = true, sscanf(data, "global-pid=%u", &pid) == 1)) { 3028 struct task_struct *p; 3029 ccs_tasklist_lock(); 3030 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 3031 if (global_pid) 3032 p = ccsecurity_exports.find_task_by_pid_ns(pid, 3033 &init_pid_ns); 3034 else 3035 p = ccsecurity_exports.find_task_by_vpid(pid); 3036 #else 3037 p = find_task_by_pid(pid); 3038 #endif 3039 if (p) 3040 domain = ccs_task_domain(p); 3041 ccs_tasklist_unlock(); 3042 } else if (!strncmp(data, "domain=", 7)) { 3043 if (*(data + 7) == '<') 3044 domain = ccs_find_domain(data + 7); 3045 } else if (sscanf(data, "Q=%u", &pid) == 1) { 3046 domain = ccs_find_domain_by_qid(pid); 3047 } else 3048 return false; 3049 head->w.domain = domain; 3050 /* Accessing read_buf is safe because head->io_sem is held. */ 3051 if (!head->read_buf) 3052 return true; /* Do nothing if open(O_WRONLY). */ 3053 memset(&head->r, 0, sizeof(head->r)); 3054 head->r.print_this_domain_only = true; 3055 if (domain) 3056 head->r.domain = &domain->list; 3057 else 3058 head->r.eof = true; 3059 ccs_io_printf(head, "# select %s\n", data); 3060 if (domain && domain->is_deleted) 3061 ccs_set_string(head, "# This is a deleted domain.\n"); 3062 return true; 3063 } 3064 3065 /** 3066 * ccs_update_acl - Update "struct ccs_acl_info" entry. 3067 * 3068 * @size: Size of new entry in bytes. 3069 * @param: Pointer to "struct ccs_acl_param". 3070 * 3071 * Returns 0 on success, negative value otherwise. 3072 * 3073 * Caller holds ccs_read_lock(). 3074 */ 3075 static int ccs_update_acl(const int size, struct ccs_acl_param *param) 3076 { 3077 struct ccs_acl_info *new_entry = ¶m->e.acl_info; 3078 const bool is_delete = param->is_delete; 3079 int error = is_delete ? -ENOENT : -ENOMEM; 3080 struct ccs_acl_info *entry; 3081 struct list_head * const list = param->list; 3082 BUG_ON(size < sizeof(*entry)); 3083 if (param->data[0]) { 3084 new_entry->cond = ccs_get_condition(param); 3085 if (!new_entry->cond) 3086 return -EINVAL; 3087 /* 3088 * Domain transition preference is allowed for only 3089 * "file execute"/"task auto_execute_handler"/ 3090 * "task denied_auto_execute_handler" entries. 3091 */ 3092 if (new_entry->cond->exec_transit && 3093 !(new_entry->type == CCS_TYPE_PATH_ACL && 3094 new_entry->perm == 1 << CCS_TYPE_EXECUTE) 3095 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3096 && new_entry->type != CCS_TYPE_AUTO_EXECUTE_HANDLER && 3097 new_entry->type != CCS_TYPE_DENIED_EXECUTE_HANDLER 3098 #endif 3099 ) 3100 return -EINVAL; 3101 } 3102 if (mutex_lock_interruptible(&ccs_policy_lock)) 3103 return -ENOMEM; 3104 list_for_each_entry_srcu(entry, list, list, &ccs_ss) { 3105 if (entry->is_deleted == CCS_GC_IN_PROGRESS) 3106 continue; 3107 if (entry->type != new_entry->type || 3108 entry->cond != new_entry->cond || 3109 memcmp(entry + 1, new_entry + 1, size - sizeof(*entry))) 3110 continue; 3111 if (is_delete) 3112 entry->perm &= ~new_entry->perm; 3113 else 3114 entry->perm |= new_entry->perm; 3115 entry->is_deleted = !entry->perm; 3116 error = 0; 3117 break; 3118 } 3119 if (error && !is_delete) { 3120 entry = ccs_commit_ok(new_entry, size); 3121 if (entry) { 3122 list_add_tail_rcu(&entry->list, list); 3123 error = 0; 3124 } 3125 } 3126 mutex_unlock(&ccs_policy_lock); 3127 return error; 3128 } 3129 3130 /** 3131 * ccs_permstr - Find permission keywords. 3132 * 3133 * @string: String representation for permissions in foo/bar/buz format. 3134 * @keyword: Keyword to find from @string/ 3135 * 3136 * Returns true if @keyword was found in @string, false otherwise. 3137 * 3138 * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2. 3139 */ 3140 static bool ccs_permstr(const char *string, const char *keyword) 3141 { 3142 const char *cp = strstr(string, keyword); 3143 if (cp) 3144 return cp == string || *(cp - 1) == '/'; 3145 return false; 3146 } 3147 3148 /** 3149 * ccs_write_task - Update task related list. 3150 * 3151 * @param: Pointer to "struct ccs_acl_param". 3152 * 3153 * Returns 0 on success, negative value otherwise. 3154 * 3155 * Caller holds ccs_read_lock(). 3156 */ 3157 static int ccs_write_task(struct ccs_acl_param *param) 3158 { 3159 int error; 3160 const bool is_auto = ccs_str_starts(¶m->data, 3161 "auto_domain_transition "); 3162 if (!is_auto && !ccs_str_starts(¶m->data, 3163 "manual_domain_transition ")) { 3164 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3165 struct ccs_handler_acl *e = ¶m->e.handler_acl; 3166 char *handler; 3167 if (ccs_str_starts(¶m->data, "auto_execute_handler ")) 3168 e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER; 3169 else if (ccs_str_starts(¶m->data, 3170 "denied_execute_handler ")) 3171 e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER; 3172 else 3173 return -EINVAL; 3174 handler = ccs_read_token(param); 3175 if (!ccs_correct_path(handler)) 3176 return -EINVAL; 3177 e->handler = ccs_get_name(handler); 3178 if (!e->handler) 3179 return -ENOMEM; 3180 if (e->handler->is_patterned) 3181 return -EINVAL; /* No patterns allowed. */ 3182 return ccs_update_acl(sizeof(*e), param); 3183 #else 3184 error = -EINVAL; 3185 #endif 3186 } else { 3187 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 3188 struct ccs_task_acl *e = ¶m->e.task_acl; 3189 e->head.type = is_auto ? 3190 CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL; 3191 e->domainname = ccs_get_domainname(param); 3192 if (!e->domainname) 3193 return -EINVAL; 3194 return ccs_update_acl(sizeof(*e), param); 3195 #else 3196 error = -EINVAL; 3197 #endif 3198 } 3199 return error; 3200 } 3201 3202 #ifdef CONFIG_CCSECURITY_NETWORK 3203 3204 /** 3205 * ccs_write_inet_network - Write "struct ccs_inet_acl" list. 3206 * 3207 * @param: Pointer to "struct ccs_acl_param". 3208 * 3209 * Returns 0 on success, negative value otherwise. 3210 * 3211 * Caller holds ccs_read_lock(). 3212 */ 3213 static int ccs_write_inet_network(struct ccs_acl_param *param) 3214 { 3215 struct ccs_inet_acl *e = ¶m->e.inet_acl; 3216 u8 type; 3217 const char *protocol = ccs_read_token(param); 3218 const char *operation = ccs_read_token(param); 3219 e->head.type = CCS_TYPE_INET_ACL; 3220 for (type = 0; type < CCS_SOCK_MAX; type++) 3221 if (!strcmp(protocol, ccs_proto_keyword[type])) 3222 break; 3223 if (type == CCS_SOCK_MAX) 3224 return -EINVAL; 3225 e->protocol = type; 3226 e->head.perm = 0; 3227 for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++) 3228 if (ccs_permstr(operation, ccs_socket_keyword[type])) 3229 e->head.perm |= 1 << type; 3230 if (!e->head.perm) 3231 return -EINVAL; 3232 if (param->data[0] == '@') { 3233 param->data++; 3234 e->address.group = ccs_get_group(param, CCS_ADDRESS_GROUP); 3235 if (!e->address.group) 3236 return -ENOMEM; 3237 } else { 3238 if (!ccs_parse_ipaddr_union(param, &e->address)) 3239 return -EINVAL; 3240 } 3241 if (!ccs_parse_number_union(param, &e->port) || 3242 e->port.values[1] > 65535) 3243 return -EINVAL; 3244 return ccs_update_acl(sizeof(*e), param); 3245 } 3246 3247 /** 3248 * ccs_write_unix_network - Write "struct ccs_unix_acl" list. 3249 * 3250 * @param: Pointer to "struct ccs_acl_param". 3251 * 3252 * Returns 0 on success, negative value otherwise. 3253 */ 3254 static int ccs_write_unix_network(struct ccs_acl_param *param) 3255 { 3256 struct ccs_unix_acl *e = ¶m->e.unix_acl; 3257 u8 type; 3258 const char *protocol = ccs_read_token(param); 3259 const char *operation = ccs_read_token(param); 3260 e->head.type = CCS_TYPE_UNIX_ACL; 3261 for (type = 0; type < CCS_SOCK_MAX; type++) 3262 if (!strcmp(protocol, ccs_proto_keyword[type])) 3263 break; 3264 if (type == CCS_SOCK_MAX) 3265 return -EINVAL; 3266 e->protocol = type; 3267 e->head.perm = 0; 3268 for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++) 3269 if (ccs_permstr(operation, ccs_socket_keyword[type])) 3270 e->head.perm |= 1 << type; 3271 if (!e->head.perm) 3272 return -EINVAL; 3273 if (!ccs_parse_name_union(param, &e->name)) 3274 return -EINVAL; 3275 return ccs_update_acl(sizeof(*e), param); 3276 } 3277 3278 #endif 3279 3280 /** 3281 * ccs_write_file - Update file related list. 3282 * 3283 * @param: Pointer to "struct ccs_acl_param". 3284 * 3285 * Returns 0 on success, negative value otherwise. 3286 * 3287 * Caller holds ccs_read_lock(). 3288 */ 3289 static int ccs_write_file(struct ccs_acl_param *param) 3290 { 3291 u16 perm = 0; 3292 u8 type; 3293 const char *operation = ccs_read_token(param); 3294 for (type = 0; type < CCS_MAX_PATH_OPERATION; type++) 3295 if (ccs_permstr(operation, ccs_path_keyword[type])) 3296 perm |= 1 << type; 3297 if (perm) { 3298 struct ccs_path_acl *e = ¶m->e.path_acl; 3299 e->head.type = CCS_TYPE_PATH_ACL; 3300 e->head.perm = perm; 3301 if (!ccs_parse_name_union(param, &e->name)) 3302 return -EINVAL; 3303 return ccs_update_acl(sizeof(*e), param); 3304 } 3305 for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++) 3306 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]])) 3307 perm |= 1 << type; 3308 if (perm) { 3309 struct ccs_path2_acl *e = ¶m->e.path2_acl; 3310 e->head.type = CCS_TYPE_PATH2_ACL; 3311 e->head.perm = perm; 3312 if (!ccs_parse_name_union(param, &e->name1) || 3313 !ccs_parse_name_union(param, &e->name2)) 3314 return -EINVAL; 3315 return ccs_update_acl(sizeof(*e), param); 3316 } 3317 for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++) 3318 if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]])) 3319 perm |= 1 << type; 3320 if (perm) { 3321 struct ccs_path_number_acl *e = ¶m->e.path_number_acl; 3322 e->head.type = CCS_TYPE_PATH_NUMBER_ACL; 3323 e->head.perm = perm; 3324 if (!ccs_parse_name_union(param, &e->name) || 3325 !ccs_parse_number_union(param, &e->number)) 3326 return -EINVAL; 3327 return ccs_update_acl(sizeof(*e), param); 3328 } 3329 for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++) 3330 if (ccs_permstr(operation, 3331 ccs_mac_keywords[ccs_pnnn2mac[type]])) 3332 perm |= 1 << type; 3333 if (perm) { 3334 struct ccs_mkdev_acl *e = ¶m->e.mkdev_acl; 3335 e->head.type = CCS_TYPE_MKDEV_ACL; 3336 e->head.perm = perm; 3337 if (!ccs_parse_name_union(param, &e->name) || 3338 !ccs_parse_number_union(param, &e->mode) || 3339 !ccs_parse_number_union(param, &e->major) || 3340 !ccs_parse_number_union(param, &e->minor)) 3341 return -EINVAL; 3342 return ccs_update_acl(sizeof(*e), param); 3343 } 3344 if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) { 3345 struct ccs_mount_acl *e = ¶m->e.mount_acl; 3346 e->head.type = CCS_TYPE_MOUNT_ACL; 3347 if (!ccs_parse_name_union(param, &e->dev_name) || 3348 !ccs_parse_name_union(param, &e->dir_name) || 3349 !ccs_parse_name_union(param, &e->fs_type) || 3350 !ccs_parse_number_union(param, &e->flags)) 3351 return -EINVAL; 3352 return ccs_update_acl(sizeof(*e), param); 3353 } 3354 return -EINVAL; 3355 } 3356 3357 #ifdef CONFIG_CCSECURITY_MISC 3358 3359 /** 3360 * ccs_write_misc - Update environment variable list. 3361 * 3362 * @param: Pointer to "struct ccs_acl_param". 3363 * 3364 * Returns 0 on success, negative value otherwise. 3365 */ 3366 static int ccs_write_misc(struct ccs_acl_param *param) 3367 { 3368 if (ccs_str_starts(¶m->data, "env ")) { 3369 struct ccs_env_acl *e = ¶m->e.env_acl; 3370 const char *data = ccs_read_token(param); 3371 e->head.type = CCS_TYPE_ENV_ACL; 3372 if (!ccs_correct_word(data) || strchr(data, '=')) 3373 return -EINVAL; 3374 e->env = ccs_get_name(data); 3375 if (!e->env) 3376 return -ENOMEM; 3377 return ccs_update_acl(sizeof(*e), param); 3378 } 3379 return -EINVAL; 3380 } 3381 3382 #endif 3383 3384 #ifdef CONFIG_CCSECURITY_IPC 3385 3386 /** 3387 * ccs_write_ipc - Update "struct ccs_signal_acl" list. 3388 * 3389 * @param: Pointer to "struct ccs_acl_param". 3390 * 3391 * Returns 0 on success, negative value otherwise. 3392 */ 3393 static int ccs_write_ipc(struct ccs_acl_param *param) 3394 { 3395 struct ccs_signal_acl *e = ¶m->e.signal_acl; 3396 e->head.type = CCS_TYPE_SIGNAL_ACL; 3397 if (!ccs_parse_number_union(param, &e->sig)) 3398 return -EINVAL; 3399 e->domainname = ccs_get_domainname(param); 3400 if (!e->domainname) 3401 return -EINVAL; 3402 return ccs_update_acl(sizeof(*e), param); 3403 } 3404 3405 #endif 3406 3407 #ifdef CONFIG_CCSECURITY_CAPABILITY 3408 3409 /** 3410 * ccs_write_capability - Write "struct ccs_capability_acl" list. 3411 * 3412 * @param: Pointer to "struct ccs_acl_param". 3413 * 3414 * Returns 0 on success, negative value otherwise. 3415 * 3416 * Caller holds ccs_read_lock(). 3417 */ 3418 static int ccs_write_capability(struct ccs_acl_param *param) 3419 { 3420 struct ccs_capability_acl *e = ¶m->e.capability_acl; 3421 const char *operation = ccs_read_token(param); 3422 u8 type; 3423 e->head.type = CCS_TYPE_CAPABILITY_ACL; 3424 for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) { 3425 if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]])) 3426 continue; 3427 e->operation = type; 3428 return ccs_update_acl(sizeof(*e), param); 3429 } 3430 return -EINVAL; 3431 } 3432 3433 #endif 3434 3435 /** 3436 * ccs_write_acl - Write "struct ccs_acl_info" list. 3437 * 3438 * @ns: Pointer to "struct ccs_policy_namespace". 3439 * @list: Pointer to "struct list_head". 3440 * @data: Policy to be interpreted. 3441 * @is_delete: True if it is a delete request. 3442 * 3443 * Returns 0 on success, negative value otherwise. 3444 * 3445 * Caller holds ccs_read_lock(). 3446 */ 3447 static int ccs_write_acl(struct ccs_policy_namespace *ns, 3448 struct list_head *list, char *data, 3449 const bool is_delete) 3450 { 3451 struct ccs_acl_param param = { 3452 .ns = ns, 3453 .list = list, 3454 .data = data, 3455 .is_delete = is_delete, 3456 }; 3457 static const struct { 3458 const char *keyword; 3459 int (*write) (struct ccs_acl_param *); 3460 } ccs_callback[] = { 3461 { "file ", ccs_write_file }, 3462 #ifdef CONFIG_CCSECURITY_NETWORK 3463 { "network inet ", ccs_write_inet_network }, 3464 { "network unix ", ccs_write_unix_network }, 3465 #endif 3466 #ifdef CONFIG_CCSECURITY_MISC 3467 { "misc ", ccs_write_misc }, 3468 #endif 3469 #ifdef CONFIG_CCSECURITY_CAPABILITY 3470 { "capability ", ccs_write_capability }, 3471 #endif 3472 #ifdef CONFIG_CCSECURITY_IPC 3473 { "ipc signal ", ccs_write_ipc }, 3474 #endif 3475 { "task ", ccs_write_task }, 3476 }; 3477 u8 i; 3478 /* Forced zero clear for using memcmp() at ccs_update_acl(). */ 3479 memset(¶m.e, 0, sizeof(param.e)); 3480 param.e.acl_info.perm = 1; 3481 for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) { 3482 int error; 3483 if (!ccs_str_starts(¶m.data, ccs_callback[i].keyword)) 3484 continue; 3485 error = ccs_callback[i].write(¶m); 3486 ccs_del_acl(¶m.e.acl_info.list); 3487 return error; 3488 } 3489 return -EINVAL; 3490 } 3491 3492 /** 3493 * ccs_delete_domain - Delete a domain. 3494 * 3495 * @domainname: The name of domain. 3496 * 3497 * Returns 0. 3498 */ 3499 static int ccs_delete_domain(char *domainname) 3500 { 3501 struct ccs_domain_info *domain; 3502 struct ccs_path_info name; 3503 name.name = domainname; 3504 ccs_fill_path_info(&name); 3505 if (mutex_lock_interruptible(&ccs_policy_lock)) 3506 return 0; 3507 /* Is there an active domain? */ 3508 list_for_each_entry_srcu(domain, &ccs_domain_list, list, &ccs_ss) { 3509 /* Never delete ccs_kernel_domain. */ 3510 if (domain == &ccs_kernel_domain) 3511 continue; 3512 if (domain->is_deleted || 3513 ccs_pathcmp(domain->domainname, &name)) 3514 continue; 3515 domain->is_deleted = true; 3516 break; 3517 } 3518 mutex_unlock(&ccs_policy_lock); 3519 return 0; 3520 } 3521 3522 /** 3523 * ccs_write_domain - Write domain policy. 3524 * 3525 * @head: Pointer to "struct ccs_io_buffer". 3526 * 3527 * Returns 0 on success, negative value otherwise. 3528 * 3529 * Caller holds ccs_read_lock(). 3530 */ 3531 static int ccs_write_domain(struct ccs_io_buffer *head) 3532 { 3533 char *data = head->write_buf; 3534 struct ccs_policy_namespace *ns; 3535 struct ccs_domain_info *domain = head->w.domain; 3536 const bool is_delete = head->w.is_delete; 3537 const bool is_select = !is_delete && ccs_str_starts(&data, "select "); 3538 unsigned int idx; 3539 if (*data == '<') { 3540 domain = NULL; 3541 if (is_delete) 3542 ccs_delete_domain(data); 3543 else if (is_select) 3544 domain = ccs_find_domain(data); 3545 else 3546 domain = ccs_assign_domain(data, false); 3547 head->w.domain = domain; 3548 return 0; 3549 } 3550 if (!domain) 3551 return -EINVAL; 3552 ns = domain->ns; 3553 if (sscanf(data, "use_profile %u\n", &idx) == 1 && 3554 idx < CCS_MAX_PROFILES) { 3555 if (!ccs_policy_loaded || ns->profile_ptr[(u8) idx]) 3556 if (!is_delete) 3557 domain->profile = (u8) idx; 3558 return 0; 3559 } 3560 if (sscanf(data, "use_group %u\n", &idx) == 1 && 3561 idx < CCS_MAX_ACL_GROUPS) { 3562 if (!is_delete) 3563 set_bit(idx, domain->group); 3564 else 3565 clear_bit(idx, domain->group); 3566 return 0; 3567 } 3568 for (idx = 0; idx < CCS_MAX_DOMAIN_INFO_FLAGS; idx++) { 3569 const char *cp = ccs_dif[idx]; 3570 if (strncmp(data, cp, strlen(cp) - 1)) 3571 continue; 3572 domain->flags[idx] = !is_delete; 3573 return 0; 3574 } 3575 return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete); 3576 } 3577 3578 /** 3579 * ccs_print_name_union - Print a ccs_name_union. 3580 * 3581 * @head: Pointer to "struct ccs_io_buffer". 3582 * @ptr: Pointer to "struct ccs_name_union". 3583 * 3584 * Returns nothing. 3585 */ 3586 static void ccs_print_name_union(struct ccs_io_buffer *head, 3587 const struct ccs_name_union *ptr) 3588 { 3589 ccs_set_space(head); 3590 if (!ccs_print_group(head, ptr->group)) 3591 ccs_set_string(head, ptr->filename->name); 3592 } 3593 3594 /** 3595 * ccs_print_name_union_quoted - Print a ccs_name_union with a quote. 3596 * 3597 * @head: Pointer to "struct ccs_io_buffer". 3598 * @ptr: Pointer to "struct ccs_name_union". 3599 * 3600 * Returns nothing. 3601 */ 3602 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head, 3603 const struct ccs_name_union *ptr) 3604 { 3605 if (!ccs_print_group(head, ptr->group)) { 3606 ccs_set_string(head, "\""); 3607 ccs_set_string(head, ptr->filename->name); 3608 ccs_set_string(head, "\""); 3609 } 3610 } 3611 3612 /** 3613 * ccs_print_number_union_nospace - Print a ccs_number_union without a space. 3614 * 3615 * @head: Pointer to "struct ccs_io_buffer". 3616 * @ptr: Pointer to "struct ccs_number_union". 3617 * 3618 * Returns nothing. 3619 */ 3620 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head, 3621 const struct ccs_number_union *ptr) 3622 { 3623 if (!ccs_print_group(head, ptr->group)) { 3624 int i; 3625 unsigned long min = ptr->values[0]; 3626 const unsigned long max = ptr->values[1]; 3627 u8 min_type = ptr->value_type[0]; 3628 const u8 max_type = ptr->value_type[1]; 3629 char buffer[128]; 3630 buffer[0] = '\0'; 3631 for (i = 0; i < 2; i++) { 3632 switch (min_type) { 3633 case CCS_VALUE_TYPE_HEXADECIMAL: 3634 ccs_addprintf(buffer, sizeof(buffer), "0x%lX", 3635 min); 3636 break; 3637 case CCS_VALUE_TYPE_OCTAL: 3638 ccs_addprintf(buffer, sizeof(buffer), "0%lo", 3639 min); 3640 break; 3641 default: 3642 ccs_addprintf(buffer, sizeof(buffer), "%lu", 3643 min); 3644 break; 3645 } 3646 if (min == max && min_type == max_type) 3647 break; 3648 ccs_addprintf(buffer, sizeof(buffer), "-"); 3649 min_type = max_type; 3650 min = max; 3651 } 3652 ccs_io_printf(head, "%s", buffer); 3653 } 3654 } 3655 3656 /** 3657 * ccs_print_number_union - Print a ccs_number_union. 3658 * 3659 * @head: Pointer to "struct ccs_io_buffer". 3660 * @ptr: Pointer to "struct ccs_number_union". 3661 * 3662 * Returns nothing. 3663 */ 3664 static void ccs_print_number_union(struct ccs_io_buffer *head, 3665 const struct ccs_number_union *ptr) 3666 { 3667 ccs_set_space(head); 3668 ccs_print_number_union_nospace(head, ptr); 3669 } 3670 3671 /** 3672 * ccs_print_condition - Print condition part. 3673 * 3674 * @head: Pointer to "struct ccs_io_buffer". 3675 * @cond: Pointer to "struct ccs_condition". 3676 * 3677 * Returns true on success, false otherwise. 3678 */ 3679 static bool ccs_print_condition(struct ccs_io_buffer *head, 3680 const struct ccs_condition *cond) 3681 { 3682 switch (head->r.cond_step) { 3683 case 0: 3684 head->r.cond_index = 0; 3685 head->r.cond_step++; 3686 if (cond->transit && cond->exec_transit) { 3687 ccs_set_space(head); 3688 ccs_set_string(head, cond->transit->name); 3689 } 3690 /* fall through */ 3691 case 1: 3692 { 3693 const u16 condc = cond->condc; 3694 const struct ccs_condition_element *condp = 3695 (typeof(condp)) (cond + 1); 3696 const struct ccs_number_union *numbers_p = 3697 (typeof(numbers_p)) (condp + condc); 3698 const struct ccs_name_union *names_p = 3699 (typeof(names_p)) 3700 (numbers_p + cond->numbers_count); 3701 const struct ccs_argv *argv = 3702 (typeof(argv)) (names_p + cond->names_count); 3703 const struct ccs_envp *envp = 3704 (typeof(envp)) (argv + cond->argc); 3705 u16 skip; 3706 for (skip = 0; skip < head->r.cond_index; skip++) { 3707 const u8 left = condp->left; 3708 const u8 right = condp->right; 3709 condp++; 3710 switch (left) { 3711 case CCS_ARGV_ENTRY: 3712 argv++; 3713 continue; 3714 case CCS_ENVP_ENTRY: 3715 envp++; 3716 continue; 3717 case CCS_NUMBER_UNION: 3718 numbers_p++; 3719 break; 3720 } 3721 switch (right) { 3722 case CCS_NAME_UNION: 3723 names_p++; 3724 break; 3725 case CCS_NUMBER_UNION: 3726 numbers_p++; 3727 break; 3728 } 3729 } 3730 while (head->r.cond_index < condc) { 3731 const u8 match = condp->equals; 3732 const u8 left = condp->left; 3733 const u8 right = condp->right; 3734 if (!ccs_flush(head)) 3735 return false; 3736 condp++; 3737 head->r.cond_index++; 3738 ccs_set_space(head); 3739 switch (left) { 3740 case CCS_ARGV_ENTRY: 3741 ccs_io_printf(head, 3742 "exec.argv[%lu]%s=\"", 3743 argv->index, 3744 argv->is_not ? "!" : ""); 3745 ccs_set_string(head, 3746 argv->value->name); 3747 ccs_set_string(head, "\""); 3748 argv++; 3749 continue; 3750 case CCS_ENVP_ENTRY: 3751 ccs_set_string(head, "exec.envp[\""); 3752 ccs_set_string(head, envp->name->name); 3753 ccs_io_printf(head, "\"]%s=", 3754 envp->is_not ? "!" : ""); 3755 if (envp->value) { 3756 ccs_set_string(head, "\""); 3757 ccs_set_string(head, envp-> 3758 value->name); 3759 ccs_set_string(head, "\""); 3760 } else { 3761 ccs_set_string(head, "NULL"); 3762 } 3763 envp++; 3764 continue; 3765 case CCS_NUMBER_UNION: 3766 ccs_print_number_union_nospace 3767 (head, numbers_p++); 3768 break; 3769 default: 3770 ccs_set_string(head, 3771 ccs_condition_keyword[left]); 3772 break; 3773 } 3774 ccs_set_string(head, match ? "=" : "!="); 3775 switch (right) { 3776 case CCS_NAME_UNION: 3777 ccs_print_name_union_quoted 3778 (head, names_p++); 3779 break; 3780 case CCS_NUMBER_UNION: 3781 ccs_print_number_union_nospace 3782 (head, numbers_p++); 3783 break; 3784 default: 3785 ccs_set_string(head, 3786 ccs_condition_keyword[right]); 3787 break; 3788 } 3789 } 3790 } 3791 head->r.cond_step++; 3792 /* fall through */ 3793 case 2: 3794 if (!ccs_flush(head)) 3795 break; 3796 head->r.cond_step++; 3797 /* fall through */ 3798 case 3: 3799 if (cond->grant_log != CCS_GRANTLOG_AUTO) 3800 ccs_io_printf(head, " grant_log=%s", 3801 ccs_yesno(cond->grant_log == 3802 CCS_GRANTLOG_YES)); 3803 if (cond->transit && !cond->exec_transit) { 3804 const char *name = cond->transit->name; 3805 ccs_set_string(head, " auto_domain_transition=\""); 3806 ccs_set_string(head, name); 3807 ccs_set_string(head, "\""); 3808 } 3809 ccs_set_lf(head); 3810 return true; 3811 } 3812 return false; 3813 } 3814 3815 /** 3816 * ccs_set_group - Print "acl_group " header keyword and category name. 3817 * 3818 * @head: Pointer to "struct ccs_io_buffer". 3819 * @category: Category name. 3820 * 3821 * Returns nothing. 3822 */ 3823 static void ccs_set_group(struct ccs_io_buffer *head, const char *category) 3824 { 3825 if (head->type == CCS_EXCEPTION_POLICY) { 3826 ccs_print_namespace(head); 3827 ccs_io_printf(head, "acl_group %u ", head->r.acl_group_index); 3828 } 3829 ccs_set_string(head, category); 3830 } 3831 3832 /** 3833 * ccs_print_entry - Print an ACL entry. 3834 * 3835 * @head: Pointer to "struct ccs_io_buffer". 3836 * @acl: Pointer to an ACL entry. 3837 * 3838 * Returns true on success, false otherwise. 3839 */ 3840 static bool ccs_print_entry(struct ccs_io_buffer *head, 3841 const struct ccs_acl_info *acl) 3842 { 3843 const u8 acl_type = acl->type; 3844 const bool may_trigger_transition = acl->cond && acl->cond->transit; 3845 bool first = true; 3846 u8 bit; 3847 if (head->r.print_cond_part) 3848 goto print_cond_part; 3849 if (acl->is_deleted) 3850 return true; 3851 if (!ccs_flush(head)) 3852 return false; 3853 else if (acl_type == CCS_TYPE_PATH_ACL) { 3854 struct ccs_path_acl *ptr 3855 = container_of(acl, typeof(*ptr), head); 3856 for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) { 3857 if (!(acl->perm & (1 << bit))) 3858 continue; 3859 if (head->r.print_transition_related_only && 3860 bit != CCS_TYPE_EXECUTE && !may_trigger_transition) 3861 continue; 3862 if (first) { 3863 ccs_set_group(head, "file "); 3864 first = false; 3865 } else { 3866 ccs_set_slash(head); 3867 } 3868 ccs_set_string(head, ccs_path_keyword[bit]); 3869 } 3870 if (first) 3871 return true; 3872 ccs_print_name_union(head, &ptr->name); 3873 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 3874 } else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER || 3875 acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) { 3876 struct ccs_handler_acl *ptr 3877 = container_of(acl, typeof(*ptr), head); 3878 ccs_set_group(head, "task "); 3879 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER 3880 ? "auto_execute_handler " : 3881 "denied_execute_handler "); 3882 ccs_set_string(head, ptr->handler->name); 3883 #endif 3884 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 3885 } else if (acl_type == CCS_TYPE_AUTO_TASK_ACL || 3886 acl_type == CCS_TYPE_MANUAL_TASK_ACL) { 3887 struct ccs_task_acl *ptr = 3888 container_of(acl, typeof(*ptr), head); 3889 ccs_set_group(head, "task "); 3890 ccs_set_string(head, acl_type == CCS_TYPE_AUTO_TASK_ACL ? 3891 "auto_domain_transition " : 3892 "manual_domain_transition "); 3893 ccs_set_string(head, ptr->domainname->name); 3894 #endif 3895 } else if (head->r.print_transition_related_only && 3896 !may_trigger_transition) { 3897 return true; 3898 } else if (acl_type == CCS_TYPE_MKDEV_ACL) { 3899 struct ccs_mkdev_acl *ptr = 3900 container_of(acl, typeof(*ptr), head); 3901 for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) { 3902 if (!(acl->perm & (1 << bit))) 3903 continue; 3904 if (first) { 3905 ccs_set_group(head, "file "); 3906 first = false; 3907 } else { 3908 ccs_set_slash(head); 3909 } 3910 ccs_set_string(head, ccs_mac_keywords 3911 [ccs_pnnn2mac[bit]]); 3912 } 3913 if (first) 3914 return true; 3915 ccs_print_name_union(head, &ptr->name); 3916 ccs_print_number_union(head, &ptr->mode); 3917 ccs_print_number_union(head, &ptr->major); 3918 ccs_print_number_union(head, &ptr->minor); 3919 } else if (acl_type == CCS_TYPE_PATH2_ACL) { 3920 struct ccs_path2_acl *ptr = 3921 container_of(acl, typeof(*ptr), head); 3922 for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) { 3923 if (!(acl->perm & (1 << bit))) 3924 continue; 3925 if (first) { 3926 ccs_set_group(head, "file "); 3927 first = false; 3928 } else { 3929 ccs_set_slash(head); 3930 } 3931 ccs_set_string(head, ccs_mac_keywords 3932 [ccs_pp2mac[bit]]); 3933 } 3934 if (first) 3935 return true; 3936 ccs_print_name_union(head, &ptr->name1); 3937 ccs_print_name_union(head, &ptr->name2); 3938 } else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) { 3939 struct ccs_path_number_acl *ptr = 3940 container_of(acl, typeof(*ptr), head); 3941 for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) { 3942 if (!(acl->perm & (1 << bit))) 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_mac_keywords 3951 [ccs_pn2mac[bit]]); 3952 } 3953 if (first) 3954 return true; 3955 ccs_print_name_union(head, &ptr->name); 3956 ccs_print_number_union(head, &ptr->number); 3957 #ifdef CONFIG_CCSECURITY_MISC 3958 } else if (acl_type == CCS_TYPE_ENV_ACL) { 3959 struct ccs_env_acl *ptr = 3960 container_of(acl, typeof(*ptr), head); 3961 ccs_set_group(head, "misc env "); 3962 ccs_set_string(head, ptr->env->name); 3963 #endif 3964 #ifdef CONFIG_CCSECURITY_CAPABILITY 3965 } else if (acl_type == CCS_TYPE_CAPABILITY_ACL) { 3966 struct ccs_capability_acl *ptr = 3967 container_of(acl, typeof(*ptr), head); 3968 ccs_set_group(head, "capability "); 3969 ccs_set_string(head, ccs_mac_keywords 3970 [ccs_c2mac[ptr->operation]]); 3971 #endif 3972 #ifdef CONFIG_CCSECURITY_NETWORK 3973 } else if (acl_type == CCS_TYPE_INET_ACL) { 3974 struct ccs_inet_acl *ptr = 3975 container_of(acl, typeof(*ptr), head); 3976 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) { 3977 if (!(acl->perm & (1 << bit))) 3978 continue; 3979 if (first) { 3980 ccs_set_group(head, "network inet "); 3981 ccs_set_string(head, ccs_proto_keyword 3982 [ptr->protocol]); 3983 ccs_set_space(head); 3984 first = false; 3985 } else { 3986 ccs_set_slash(head); 3987 } 3988 ccs_set_string(head, ccs_socket_keyword[bit]); 3989 } 3990 if (first) 3991 return true; 3992 ccs_set_space(head); 3993 if (!ccs_print_group(head, ptr->address.group)) { 3994 char buf[128]; 3995 ccs_print_ip(buf, sizeof(buf), &ptr->address); 3996 ccs_io_printf(head, "%s", buf); 3997 } 3998 ccs_print_number_union(head, &ptr->port); 3999 } else if (acl_type == CCS_TYPE_UNIX_ACL) { 4000 struct ccs_unix_acl *ptr = 4001 container_of(acl, typeof(*ptr), head); 4002 for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) { 4003 if (!(acl->perm & (1 << bit))) 4004 continue; 4005 if (first) { 4006 ccs_set_group(head, "network unix "); 4007 ccs_set_string(head, ccs_proto_keyword 4008 [ptr->protocol]); 4009 ccs_set_space(head); 4010 first = false; 4011 } else { 4012 ccs_set_slash(head); 4013 } 4014 ccs_set_string(head, ccs_socket_keyword[bit]); 4015 } 4016 if (first) 4017 return true; 4018 ccs_print_name_union(head, &ptr->name); 4019 #endif 4020 #ifdef CONFIG_CCSECURITY_IPC 4021 } else if (acl_type == CCS_TYPE_SIGNAL_ACL) { 4022 struct ccs_signal_acl *ptr = 4023 container_of(acl, typeof(*ptr), head); 4024 ccs_set_group(head, "ipc signal "); 4025 ccs_print_number_union_nospace(head, &ptr->sig); 4026 ccs_set_space(head); 4027 ccs_set_string(head, ptr->domainname->name); 4028 #endif 4029 } else if (acl_type == CCS_TYPE_MOUNT_ACL) { 4030 struct ccs_mount_acl *ptr = 4031 container_of(acl, typeof(*ptr), head); 4032 ccs_set_group(head, "file mount"); 4033 ccs_print_name_union(head, &ptr->dev_name); 4034 ccs_print_name_union(head, &ptr->dir_name); 4035 ccs_print_name_union(head, &ptr->fs_type); 4036 ccs_print_number_union(head, &ptr->flags); 4037 } 4038 if (acl->cond) { 4039 head->r.print_cond_part = true; 4040 head->r.cond_step = 0; 4041 if (!ccs_flush(head)) 4042 return false; 4043 print_cond_part: 4044 if (!ccs_print_condition(head, acl->cond)) 4045 return false; 4046 head->r.print_cond_part = false; 4047 } else { 4048 ccs_set_lf(head); 4049 } 4050 return true; 4051 } 4052 4053 /** 4054 * ccs_read_acl - Read "struct ccs_acl_info" list. 4055 * 4056 * @head: Pointer to "struct ccs_io_buffer". 4057 * @list: Pointer to "struct list_head". 4058 * 4059 * Returns true on success, false otherwise. 4060 * 4061 * Caller holds ccs_read_lock(). 4062 */ 4063 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list) 4064 { 4065 list_for_each_cookie(head->r.acl, list) { 4066 struct ccs_acl_info *ptr = 4067 list_entry(head->r.acl, typeof(*ptr), list); 4068 if (!ccs_print_entry(head, ptr)) 4069 return false; 4070 } 4071 head->r.acl = NULL; 4072 return true; 4073 } 4074 4075 /** 4076 * ccs_read_domain - Read domain policy. 4077 * 4078 * @head: Pointer to "struct ccs_io_buffer". 4079 * 4080 * Returns nothing. 4081 * 4082 * Caller holds ccs_read_lock(). 4083 */ 4084 static void ccs_read_domain(struct ccs_io_buffer *head) 4085 { 4086 if (head->r.eof) 4087 return; 4088 list_for_each_cookie(head->r.domain, &ccs_domain_list) { 4089 struct ccs_domain_info *domain = 4090 list_entry(head->r.domain, typeof(*domain), list); 4091 switch (head->r.step) { 4092 u8 i; 4093 case 0: 4094 if (domain->is_deleted && 4095 !head->r.print_this_domain_only) 4096 continue; 4097 /* Print domainname and flags. */ 4098 ccs_set_string(head, domain->domainname->name); 4099 ccs_set_lf(head); 4100 ccs_io_printf(head, "use_profile %u\n", 4101 domain->profile); 4102 for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++) 4103 if (domain->flags[i]) 4104 ccs_set_string(head, ccs_dif[i]); 4105 head->r.index = 0; 4106 head->r.step++; 4107 /* fall through */ 4108 case 1: 4109 while (head->r.index < CCS_MAX_ACL_GROUPS) { 4110 i = head->r.index++; 4111 if (!test_bit(i, domain->group)) 4112 continue; 4113 ccs_io_printf(head, "use_group %u\n", i); 4114 if (!ccs_flush(head)) 4115 return; 4116 } 4117 head->r.index = 0; 4118 head->r.step++; 4119 ccs_set_lf(head); 4120 /* fall through */ 4121 case 2: 4122 if (!ccs_read_acl(head, &domain->acl_info_list)) 4123 return; 4124 head->r.step++; 4125 if (!ccs_set_lf(head)) 4126 return; 4127 /* fall through */ 4128 case 3: 4129 head->r.step = 0; 4130 if (head->r.print_this_domain_only) 4131 goto done; 4132 } 4133 } 4134 done: 4135 head->r.eof = true; 4136 } 4137 4138 /** 4139 * ccs_write_pid - Specify PID to obtain domainname. 4140 * 4141 * @head: Pointer to "struct ccs_io_buffer". 4142 * 4143 * Returns 0. 4144 */ 4145 static int ccs_write_pid(struct ccs_io_buffer *head) 4146 { 4147 head->r.eof = false; 4148 return 0; 4149 } 4150 4151 /** 4152 * ccs_read_pid - Read information of a process. 4153 * 4154 * @head: Pointer to "struct ccs_io_buffer". 4155 * 4156 * Returns the domainname which the specified PID is in or 4157 * process information of the specified PID on success, 4158 * empty string otherwise. 4159 * 4160 * Caller holds ccs_read_lock(). 4161 */ 4162 static void ccs_read_pid(struct ccs_io_buffer *head) 4163 { 4164 char *buf = head->write_buf; 4165 bool task_info = false; 4166 bool global_pid = false; 4167 unsigned int pid; 4168 struct task_struct *p; 4169 struct ccs_domain_info *domain = NULL; 4170 u32 ccs_flags = 0; 4171 /* Accessing write_buf is safe because head->io_sem is held. */ 4172 if (!buf) { 4173 head->r.eof = true; 4174 return; /* Do nothing if open(O_RDONLY). */ 4175 } 4176 if (head->r.w_pos || head->r.eof) 4177 return; 4178 head->r.eof = true; 4179 if (ccs_str_starts(&buf, "info ")) 4180 task_info = true; 4181 if (ccs_str_starts(&buf, "global-pid ")) 4182 global_pid = true; 4183 pid = (unsigned int) simple_strtoul(buf, NULL, 10); 4184 ccs_tasklist_lock(); 4185 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 4186 if (global_pid) 4187 p = ccsecurity_exports.find_task_by_pid_ns(pid, &init_pid_ns); 4188 else 4189 p = ccsecurity_exports.find_task_by_vpid(pid); 4190 #else 4191 p = find_task_by_pid(pid); 4192 #endif 4193 if (p) { 4194 domain = ccs_task_domain(p); 4195 ccs_flags = ccs_task_flags(p); 4196 } 4197 ccs_tasklist_unlock(); 4198 if (!domain) 4199 return; 4200 if (!task_info) { 4201 ccs_io_printf(head, "%u %u ", pid, domain->profile); 4202 ccs_set_string(head, domain->domainname->name); 4203 } else { 4204 ccs_io_printf(head, "%u manager=%s execute_handler=%s ", pid, 4205 ccs_yesno(ccs_flags & 4206 CCS_TASK_IS_MANAGER), 4207 ccs_yesno(ccs_flags & 4208 CCS_TASK_IS_EXECUTE_HANDLER)); 4209 } 4210 } 4211 4212 /** 4213 * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list. 4214 * 4215 * @param: Pointer to "struct ccs_acl_param". 4216 * @type: Type of this group. 4217 * 4218 * Returns 0 on success, negative value otherwise. 4219 */ 4220 static int ccs_write_group(struct ccs_acl_param *param, const u8 type) 4221 { 4222 struct ccs_group *group = ccs_get_group(param, type); 4223 int error = -EINVAL; 4224 if (!group) 4225 return -ENOMEM; 4226 param->list = &group->member_list; 4227 if (type == CCS_PATH_GROUP) { 4228 struct ccs_path_group *e = ¶m->e.path_group; 4229 e->member_name = ccs_get_name(ccs_read_token(param)); 4230 if (!e->member_name) { 4231 error = -ENOMEM; 4232 goto out; 4233 } 4234 error = ccs_update_policy(sizeof(*e), param); 4235 ccs_put_name(e->member_name); 4236 } else if (type == CCS_NUMBER_GROUP) { 4237 struct ccs_number_group *e = ¶m->e.number_group; 4238 if (param->data[0] == '@' || 4239 !ccs_parse_number_union(param, &e->number)) 4240 goto out; 4241 error = ccs_update_policy(sizeof(*e), param); 4242 #ifdef CONFIG_CCSECURITY_NETWORK 4243 } else { 4244 struct ccs_address_group *e = ¶m->e.address_group; 4245 if (param->data[0] == '@' || 4246 !ccs_parse_ipaddr_union(param, &e->address)) 4247 goto out; 4248 error = ccs_update_policy(sizeof(*e), param); 4249 #endif 4250 } 4251 out: 4252 ccs_put_group(group); 4253 return error; 4254 } 4255 4256 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4257 /** 4258 * ccs_lport_reserved - Check whether local port is reserved or not. 4259 * 4260 * @port: Port number. 4261 * 4262 * Returns true if local port is reserved, false otherwise. 4263 */ 4264 static bool __ccs_lport_reserved(const u16 port) 4265 { 4266 return ccs_reserved_port_map[port >> 3] & (1 << (port & 7)) 4267 ? true : false; 4268 } 4269 4270 /** 4271 * ccs_write_reserved_port - Update "struct ccs_reserved" list. 4272 * 4273 * @param: Pointer to "struct ccs_acl_param". 4274 * 4275 * Returns 0 on success, negative value otherwise. 4276 * 4277 * Caller holds ccs_read_lock(). 4278 */ 4279 static int ccs_write_reserved_port(struct ccs_acl_param *param) 4280 { 4281 struct ccs_reserved *e = ¶m->e.reserved; 4282 struct ccs_policy_namespace *ns = param->ns; 4283 int error; 4284 u8 *tmp; 4285 if (param->data[0] == '@' || 4286 !ccs_parse_number_union(param, &e->port) || 4287 e->port.values[1] > 65535 || param->data[0]) 4288 return -EINVAL; 4289 param->list = &ns->policy_list[CCS_ID_RESERVEDPORT]; 4290 error = ccs_update_policy(sizeof(*e), param); 4291 if (error) 4292 return error; 4293 tmp = kzalloc(sizeof(ccs_reserved_port_map), CCS_GFP_FLAGS); 4294 if (!tmp) 4295 return -ENOMEM; 4296 list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list, 4297 &ccs_ss) { 4298 struct ccs_reserved *ptr; 4299 struct list_head *list = &ns->policy_list[CCS_ID_RESERVEDPORT]; 4300 list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) { 4301 unsigned int port; 4302 if (ptr->head.is_deleted) 4303 continue; 4304 for (port = ptr->port.values[0]; 4305 port <= ptr->port.values[1]; port++) 4306 tmp[port >> 3] |= 1 << (port & 7); 4307 } 4308 } 4309 memmove(ccs_reserved_port_map, tmp, sizeof(ccs_reserved_port_map)); 4310 kfree(tmp); 4311 /* 4312 * Since this feature is no-op by default, we don't need to register 4313 * this callback hook unless the first entry is added. 4314 */ 4315 ccsecurity_ops.lport_reserved = __ccs_lport_reserved; 4316 return 0; 4317 } 4318 #endif 4319 4320 /** 4321 * ccs_write_aggregator - Write "struct ccs_aggregator" list. 4322 * 4323 * @param: Pointer to "struct ccs_acl_param". 4324 * 4325 * Returns 0 on success, negative value otherwise. 4326 */ 4327 static int ccs_write_aggregator(struct ccs_acl_param *param) 4328 { 4329 struct ccs_aggregator *e = ¶m->e.aggregator; 4330 int error = param->is_delete ? -ENOENT : -ENOMEM; 4331 const char *original_name = ccs_read_token(param); 4332 const char *aggregated_name = ccs_read_token(param); 4333 if (!ccs_correct_word(original_name) || 4334 !ccs_correct_path(aggregated_name)) 4335 return -EINVAL; 4336 e->original_name = ccs_get_name(original_name); 4337 e->aggregated_name = ccs_get_name(aggregated_name); 4338 if (!e->original_name || !e->aggregated_name || 4339 e->aggregated_name->is_patterned) /* No patterns allowed. */ 4340 goto out; 4341 param->list = ¶m->ns->policy_list[CCS_ID_AGGREGATOR]; 4342 error = ccs_update_policy(sizeof(*e), param); 4343 out: 4344 ccs_put_name(e->original_name); 4345 ccs_put_name(e->aggregated_name); 4346 return error; 4347 } 4348 4349 /** 4350 * ccs_write_transition_control - Write "struct ccs_transition_control" list. 4351 * 4352 * @param: Pointer to "struct ccs_acl_param". 4353 * @type: Type of this entry. 4354 * 4355 * Returns 0 on success, negative value otherwise. 4356 */ 4357 static int ccs_write_transition_control(struct ccs_acl_param *param, 4358 const u8 type) 4359 { 4360 struct ccs_transition_control *e = ¶m->e.transition_control; 4361 int error = param->is_delete ? -ENOENT : -ENOMEM; 4362 char *program = param->data; 4363 char *domainname = strstr(program, " from "); 4364 e->type = type; 4365 if (domainname) { 4366 *domainname = '\0'; 4367 domainname += 6; 4368 } else if (type == CCS_TRANSITION_CONTROL_NO_KEEP || 4369 type == CCS_TRANSITION_CONTROL_KEEP) { 4370 domainname = program; 4371 program = NULL; 4372 } 4373 if (program && strcmp(program, "any")) { 4374 if (!ccs_correct_path(program)) 4375 return -EINVAL; 4376 e->program = ccs_get_name(program); 4377 if (!e->program) 4378 goto out; 4379 } 4380 if (domainname && strcmp(domainname, "any")) { 4381 if (!ccs_correct_domain(domainname)) { 4382 if (!ccs_correct_path(domainname)) 4383 goto out; 4384 e->is_last_name = true; 4385 } 4386 e->domainname = ccs_get_name(domainname); 4387 if (!e->domainname) 4388 goto out; 4389 } 4390 param->list = ¶m->ns->policy_list[CCS_ID_TRANSITION_CONTROL]; 4391 error = ccs_update_policy(sizeof(*e), param); 4392 out: 4393 ccs_put_name(e->domainname); 4394 ccs_put_name(e->program); 4395 return error; 4396 } 4397 4398 /** 4399 * ccs_write_exception - Write exception policy. 4400 * 4401 * @head: Pointer to "struct ccs_io_buffer". 4402 * 4403 * Returns 0 on success, negative value otherwise. 4404 */ 4405 static int ccs_write_exception(struct ccs_io_buffer *head) 4406 { 4407 const bool is_delete = head->w.is_delete; 4408 struct ccs_acl_param param = { 4409 .ns = head->w.ns, 4410 .is_delete = is_delete, 4411 .data = head->write_buf, 4412 }; 4413 u8 i; 4414 /* Forced zero clear for using memcmp() at ccs_update_policy(). */ 4415 memset(¶m.e, 0, sizeof(param.e)); 4416 if (ccs_str_starts(¶m.data, "aggregator ")) 4417 return ccs_write_aggregator(¶m); 4418 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4419 if (ccs_str_starts(¶m.data, "deny_autobind ")) 4420 return ccs_write_reserved_port(¶m); 4421 #endif 4422 for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++) 4423 if (ccs_str_starts(¶m.data, ccs_transition_type[i])) 4424 return ccs_write_transition_control(¶m, i); 4425 for (i = 0; i < CCS_MAX_GROUP; i++) 4426 if (ccs_str_starts(¶m.data, ccs_group_name[i])) 4427 return ccs_write_group(¶m, i); 4428 if (ccs_str_starts(¶m.data, "acl_group ")) { 4429 unsigned int group; 4430 char *data; 4431 group = simple_strtoul(param.data, &data, 10); 4432 if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ') 4433 return ccs_write_acl(head->w.ns, 4434 &head->w.ns->acl_group[group], 4435 data, is_delete); 4436 } 4437 return -EINVAL; 4438 } 4439 4440 /** 4441 * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list. 4442 * 4443 * @head: Pointer to "struct ccs_io_buffer". 4444 * @idx: Index number. 4445 * 4446 * Returns true on success, false otherwise. 4447 * 4448 * Caller holds ccs_read_lock(). 4449 */ 4450 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx) 4451 { 4452 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4453 namespace_list); 4454 struct list_head *list = &ns->group_list[idx]; 4455 list_for_each_cookie(head->r.group, list) { 4456 struct ccs_group *group = 4457 list_entry(head->r.group, typeof(*group), head.list); 4458 list_for_each_cookie(head->r.acl, &group->member_list) { 4459 struct ccs_acl_head *ptr = 4460 list_entry(head->r.acl, typeof(*ptr), list); 4461 if (ptr->is_deleted) 4462 continue; 4463 if (!ccs_flush(head)) 4464 return false; 4465 ccs_print_namespace(head); 4466 ccs_set_string(head, ccs_group_name[idx]); 4467 ccs_set_string(head, group->group_name->name); 4468 if (idx == CCS_PATH_GROUP) { 4469 ccs_set_space(head); 4470 ccs_set_string(head, container_of 4471 (ptr, struct ccs_path_group, 4472 head)->member_name->name); 4473 } else if (idx == CCS_NUMBER_GROUP) { 4474 ccs_print_number_union(head, &container_of 4475 (ptr, struct ccs_number_group, 4476 head)->number); 4477 #ifdef CONFIG_CCSECURITY_NETWORK 4478 } else if (idx == CCS_ADDRESS_GROUP) { 4479 char buffer[128]; 4480 struct ccs_address_group *member = 4481 container_of(ptr, typeof(*member), 4482 head); 4483 ccs_print_ip(buffer, sizeof(buffer), 4484 &member->address); 4485 ccs_io_printf(head, " %s", buffer); 4486 #endif 4487 } 4488 ccs_set_lf(head); 4489 } 4490 head->r.acl = NULL; 4491 } 4492 head->r.group = NULL; 4493 return true; 4494 } 4495 4496 /** 4497 * ccs_read_policy - Read "struct ccs_..._entry" list. 4498 * 4499 * @head: Pointer to "struct ccs_io_buffer". 4500 * @idx: Index number. 4501 * 4502 * Returns true on success, false otherwise. 4503 * 4504 * Caller holds ccs_read_lock(). 4505 */ 4506 static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx) 4507 { 4508 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4509 namespace_list); 4510 struct list_head *list = &ns->policy_list[idx]; 4511 list_for_each_cookie(head->r.acl, list) { 4512 struct ccs_acl_head *acl = 4513 container_of(head->r.acl, typeof(*acl), list); 4514 if (acl->is_deleted) 4515 continue; 4516 if (head->r.print_transition_related_only && 4517 idx != CCS_ID_TRANSITION_CONTROL) 4518 continue; 4519 if (!ccs_flush(head)) 4520 return false; 4521 switch (idx) { 4522 case CCS_ID_TRANSITION_CONTROL: 4523 { 4524 struct ccs_transition_control *ptr = 4525 container_of(acl, typeof(*ptr), head); 4526 ccs_print_namespace(head); 4527 ccs_set_string(head, 4528 ccs_transition_type[ptr->type]); 4529 ccs_set_string(head, ptr->program ? 4530 ptr->program->name : "any"); 4531 ccs_set_string(head, " from "); 4532 ccs_set_string(head, ptr->domainname ? 4533 ptr->domainname->name : "any"); 4534 } 4535 break; 4536 case CCS_ID_AGGREGATOR: 4537 { 4538 struct ccs_aggregator *ptr = 4539 container_of(acl, typeof(*ptr), head); 4540 ccs_print_namespace(head); 4541 ccs_set_string(head, "aggregator "); 4542 ccs_set_string(head, ptr->original_name->name); 4543 ccs_set_space(head); 4544 ccs_set_string(head, 4545 ptr->aggregated_name->name); 4546 } 4547 break; 4548 #ifdef CONFIG_CCSECURITY_PORTRESERVE 4549 case CCS_ID_RESERVEDPORT: 4550 { 4551 struct ccs_reserved *ptr = 4552 container_of(acl, typeof(*ptr), head); 4553 ccs_print_namespace(head); 4554 ccs_set_string(head, "deny_autobind "); 4555 ccs_print_number_union_nospace(head, 4556 &ptr->port); 4557 } 4558 break; 4559 #endif 4560 default: 4561 continue; 4562 } 4563 ccs_set_lf(head); 4564 } 4565 head->r.acl = NULL; 4566 return true; 4567 } 4568 4569 /** 4570 * ccs_read_exception - Read exception policy. 4571 * 4572 * @head: Pointer to "struct ccs_io_buffer". 4573 * 4574 * Returns nothing. 4575 * 4576 * Caller holds ccs_read_lock(). 4577 */ 4578 static void ccs_read_exception(struct ccs_io_buffer *head) 4579 { 4580 struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns), 4581 namespace_list); 4582 if (head->r.eof) 4583 return; 4584 while (head->r.step < CCS_MAX_POLICY && 4585 ccs_read_policy(head, head->r.step)) 4586 head->r.step++; 4587 if (head->r.step < CCS_MAX_POLICY) 4588 return; 4589 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP && 4590 ccs_read_group(head, head->r.step - CCS_MAX_POLICY)) 4591 head->r.step++; 4592 if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP) 4593 return; 4594 while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP 4595 + CCS_MAX_ACL_GROUPS) { 4596 head->r.acl_group_index = 4597 head->r.step - CCS_MAX_POLICY - CCS_MAX_GROUP; 4598 if (!ccs_read_acl(head, &ns->acl_group 4599 [head->r.acl_group_index])) 4600 return; 4601 head->r.step++; 4602 } 4603 head->r.eof = true; 4604 } 4605 4606 /** 4607 * ccs_truncate - Truncate a line. 4608 * 4609 * @str: String to truncate. 4610 * 4611 * Returns length of truncated @str. 4612 */ 4613 static int ccs_truncate(char *str) 4614 { 4615 char *start = str; 4616 while (*(unsigned char *) str > (unsigned char) ' ') 4617 str++; 4618 *str = '\0'; 4619 return strlen(start) + 1; 4620 } 4621 4622 /** 4623 * ccs_add_entry - Add an ACL to current thread's domain. Used by learning mode. 4624 * 4625 * @header: Lines containing ACL. 4626 * 4627 * Returns nothing. 4628 */ 4629 static void ccs_add_entry(char *header) 4630 { 4631 char *buffer; 4632 char *realpath = NULL; 4633 char *argv0 = NULL; 4634 char *symlink = NULL; 4635 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4636 char *handler; 4637 #endif 4638 char *cp = strchr(header, '\n'); 4639 int len; 4640 if (!cp) 4641 return; 4642 cp = strchr(cp + 1, '\n'); 4643 if (!cp) 4644 return; 4645 *cp++ = '\0'; 4646 len = strlen(cp) + 1; 4647 /* strstr() will return NULL if ordering is wrong. */ 4648 if (*cp == 'f') { 4649 argv0 = strstr(header, " argv[]={ \""); 4650 if (argv0) { 4651 argv0 += 10; 4652 len += ccs_truncate(argv0) + 14; 4653 } 4654 realpath = strstr(header, " exec={ realpath=\""); 4655 if (realpath) { 4656 realpath += 8; 4657 len += ccs_truncate(realpath) + 6; 4658 } 4659 symlink = strstr(header, " symlink.target=\""); 4660 if (symlink) 4661 len += ccs_truncate(symlink + 1) + 1; 4662 } 4663 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4664 handler = strstr(header, "type=execute_handler"); 4665 if (handler) 4666 len += ccs_truncate(handler) + 6; 4667 #endif 4668 buffer = kmalloc(len, CCS_GFP_FLAGS); 4669 if (!buffer) 4670 return; 4671 snprintf(buffer, len - 1, "%s", cp); 4672 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4673 if (handler) 4674 ccs_addprintf(buffer, len, " task.%s", handler); 4675 #endif 4676 if (realpath) 4677 ccs_addprintf(buffer, len, " exec.%s", realpath); 4678 if (argv0) 4679 ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0); 4680 if (symlink) 4681 ccs_addprintf(buffer, len, "%s", symlink); 4682 ccs_normalize_line(buffer); 4683 { 4684 struct ccs_domain_info *domain = ccs_current_domain(); 4685 if (!ccs_write_acl(domain->ns, &domain->acl_info_list, 4686 buffer, false)) 4687 ccs_update_stat(CCS_STAT_POLICY_UPDATES); 4688 } 4689 kfree(buffer); 4690 } 4691 4692 /** 4693 * ccs_domain_quota_ok - Check for domain's quota. 4694 * 4695 * @r: Pointer to "struct ccs_request_info". 4696 * 4697 * Returns true if the domain is not exceeded quota, false otherwise. 4698 * 4699 * Caller holds ccs_read_lock(). 4700 */ 4701 static bool ccs_domain_quota_ok(struct ccs_request_info *r) 4702 { 4703 unsigned int count = 0; 4704 struct ccs_domain_info * const domain = ccs_current_domain(); 4705 struct ccs_acl_info *ptr; 4706 if (r->mode != CCS_CONFIG_LEARNING) 4707 return false; 4708 if (!domain) 4709 return true; 4710 list_for_each_entry_srcu(ptr, &domain->acl_info_list, list, &ccs_ss) { 4711 u16 perm; 4712 u8 i; 4713 if (ptr->is_deleted) 4714 continue; 4715 switch (ptr->type) { 4716 case CCS_TYPE_PATH_ACL: 4717 case CCS_TYPE_PATH2_ACL: 4718 case CCS_TYPE_PATH_NUMBER_ACL: 4719 case CCS_TYPE_MKDEV_ACL: 4720 #ifdef CONFIG_CCSECURITY_NETWORK 4721 case CCS_TYPE_INET_ACL: 4722 case CCS_TYPE_UNIX_ACL: 4723 #endif 4724 perm = ptr->perm; 4725 break; 4726 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER 4727 case CCS_TYPE_AUTO_EXECUTE_HANDLER: 4728 case CCS_TYPE_DENIED_EXECUTE_HANDLER: 4729 #endif 4730 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION 4731 case CCS_TYPE_AUTO_TASK_ACL: 4732 case CCS_TYPE_MANUAL_TASK_ACL: 4733 #endif 4734 perm = 0; 4735 break; 4736 default: 4737 perm = 1; 4738 } 4739 for (i = 0; i < 16; i++) 4740 if (perm & (1 << i)) 4741 count++; 4742 } 4743 if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY]) 4744 return true; 4745 if (!domain->flags[CCS_DIF_QUOTA_WARNED]) { 4746 domain->flags[CCS_DIF_QUOTA_WARNED] = true; 4747 /* r->granted = false; */ 4748 ccs_write_log(r, "%s", ccs_dif[CCS_DIF_QUOTA_WARNED]); 4749 printk(KERN_WARNING "WARNING: " 4750 "Domain '%s' has too many ACLs to hold. " 4751 "Stopped learning mode.\n", domain->domainname->name); 4752 } 4753 return false; 4754 } 4755 4756 /** 4757 * ccs_supervisor - Ask for the supervisor's decision. 4758 * 4759 * @r: Pointer to "struct ccs_request_info". 4760 * @fmt: The printf()'s format string, followed by parameters. 4761 * 4762 * Returns 0 if the supervisor decided to permit the access request which 4763 * violated the policy in enforcing mode, CCS_RETRY_REQUEST if the supervisor 4764 * decided to retry the access request which violated the policy in enforcing 4765 * mode, 0 if it is not in enforcing mode, -EPERM otherwise. 4766 */ 4767 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...) 4768 { 4769 va_list args; 4770 int error; 4771 int len; 4772 static unsigned int ccs_serial; 4773 struct ccs_query entry = { }; 4774 bool quota_exceeded = false; 4775 va_start(args, fmt); 4776 len = vsnprintf((char *) &len, 1, fmt, args) + 1; 4777 va_end(args); 4778 /* Write /proc/ccs/audit. */ 4779 va_start(args, fmt); 4780 ccs_write_log2(r, len, fmt, args); 4781 va_end(args); 4782 /* Nothing more to do if granted. */ 4783 if (r->granted) 4784 return 0; 4785 if (r->mode) 4786 ccs_update_stat(r->mode); 4787 switch (r->mode) { 4788 int i; 4789 struct ccs_profile *p; 4790 case CCS_CONFIG_ENFORCING: 4791 error = -EPERM; 4792 if (atomic_read(&ccs_query_observers)) 4793 break; 4794 if (r->dont_sleep_on_enforce_error) 4795 goto out; 4796 p = ccs_profile(r->profile); 4797 /* Check enforcing_penalty parameter. */ 4798 for (i = 0; i < p->pref[CCS_PREF_ENFORCING_PENALTY]; i++) { 4799 set_current_state(TASK_INTERRUPTIBLE); 4800 schedule_timeout(HZ / 10); 4801 } 4802 goto out; 4803 case CCS_CONFIG_LEARNING: 4804 error = 0; 4805 /* Check max_learning_entry parameter. */ 4806 if (ccs_domain_quota_ok(r)) 4807 break; 4808 /* fall through */ 4809 default: 4810 return 0; 4811 } 4812 /* Get message. */ 4813 va_start(args, fmt); 4814 entry.query = ccs_init_log(r, len, fmt, args); 4815 va_end(args); 4816 if (!entry.query) 4817 goto out; 4818 entry.query_len = strlen(entry.query) + 1; 4819 if (!error) { 4820 ccs_add_entry(entry.query); 4821 goto out; 4822 } 4823 len = ccs_round2(entry.query_len); 4824 entry.domain = ccs_current_domain(); 4825 spin_lock(&ccs_query_list_lock); 4826 if (ccs_memory_quota[CCS_MEMORY_QUERY] && 4827 ccs_memory_used[CCS_MEMORY_QUERY] + len 4828 >= ccs_memory_quota[CCS_MEMORY_QUERY]) { 4829 quota_exceeded = true; 4830 } else { 4831 entry.serial = ccs_serial++; 4832 entry.retry = r->retry; 4833 ccs_memory_used[CCS_MEMORY_QUERY] += len; 4834 list_add_tail(&entry.list, &ccs_query_list); 4835 } 4836 spin_unlock(&ccs_query_list_lock); 4837 if (quota_exceeded) 4838 goto out; 4839 /* Give 10 seconds for supervisor's opinion. */ 4840 while (entry.timer < 10) { 4841 wake_up_all(&ccs_query_wait); 4842 if (wait_event_interruptible_timeout 4843 (ccs_answer_wait, entry.answer || 4844 !atomic_read(&ccs_query_observers), HZ)) 4845 break; 4846 else 4847 entry.timer++; 4848 } 4849 spin_lock(&ccs_query_list_lock); 4850 list_del(&entry.list); 4851 ccs_memory_used[CCS_MEMORY_QUERY] -= len; 4852 spin_unlock(&ccs_query_list_lock); 4853 switch (entry.answer) { 4854 case 3: /* Asked to retry by administrator. */ 4855 error = CCS_RETRY_REQUEST; 4856 r->retry++; 4857 break; 4858 case 1: 4859 /* Granted by administrator. */ 4860 error = 0; 4861 break; 4862 default: 4863 /* Timed out or rejected by administrator. */ 4864 break; 4865 } 4866 out: 4867 kfree(entry.query); 4868 return error; 4869 } 4870 4871 /** 4872 * ccs_audit_log - Audit permission check log. 4873 * 4874 * @r: Pointer to "struct ccs_request_info". 4875 * 4876 * Returns return value of ccs_supervisor(). 4877 */ 4878 int ccs_audit_log(struct ccs_request_info *r) 4879 { 4880 switch (r->param_type) { 4881 u8 type; 4882 char buf[48]; 4883 #ifdef CONFIG_CCSECURITY_NETWORK 4884 const u32 *address; 4885 #endif 4886 case CCS_TYPE_PATH_ACL: 4887 return ccs_supervisor(r, "file %s %s\n", ccs_path_keyword 4888 [r->param.path.operation], 4889 r->param.path.filename->name); 4890 case CCS_TYPE_PATH2_ACL: 4891 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords 4892 [ccs_pp2mac[r->param.path2.operation]], 4893 r->param.path2.filename1->name, 4894 r->param.path2.filename2->name); 4895 case CCS_TYPE_PATH_NUMBER_ACL: 4896 type = r->param.path_number.operation; 4897 switch (type) { 4898 case CCS_TYPE_CREATE: 4899 case CCS_TYPE_MKDIR: 4900 case CCS_TYPE_MKFIFO: 4901 case CCS_TYPE_MKSOCK: 4902 case CCS_TYPE_CHMOD: 4903 snprintf(buf, sizeof(buf), "0%lo", 4904 r->param.path_number.number); 4905 break; 4906 case CCS_TYPE_IOCTL: 4907 snprintf(buf, sizeof(buf), "0x%lX", 4908 r->param.path_number.number); 4909 break; 4910 default: 4911 snprintf(buf, sizeof(buf), "%lu", 4912 r->param.path_number.number); 4913 break; 4914 } 4915 return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords 4916 [ccs_pn2mac[type]], 4917 r->param.path_number.filename->name, 4918 buf); 4919 case CCS_TYPE_MKDEV_ACL: 4920 return ccs_supervisor(r, "file %s %s 0%o %u %u\n", 4921 ccs_mac_keywords 4922 [ccs_pnnn2mac[r->param.mkdev.operation]], 4923 r->param.mkdev.filename->name, 4924 r->param.mkdev.mode, 4925 r->param.mkdev.major, 4926 r->param.mkdev.minor); 4927 case CCS_TYPE_MOUNT_ACL: 4928 return ccs_supervisor(r, "file mount %s %s %s 0x%lX\n", 4929 r->param.mount.dev->name, 4930 r->param.mount.dir->name, 4931 r->param.mount.type->name, 4932 r->param.mount.flags); 4933 #ifdef CONFIG_CCSECURITY_MISC 4934 case CCS_TYPE_ENV_ACL: 4935 return ccs_supervisor(r, "misc env %s\n", 4936 r->param.environ.name->name); 4937 #endif 4938 #ifdef CONFIG_CCSECURITY_CAPABILITY 4939 case CCS_TYPE_CAPABILITY_ACL: 4940 return ccs_supervisor(r, "capability %s\n", ccs_mac_keywords 4941 [ccs_c2mac[r->param.capability. 4942 operation]]); 4943 #endif 4944 #ifdef CONFIG_CCSECURITY_NETWORK 4945 case CCS_TYPE_INET_ACL: 4946 address = r->param.inet_network.address; 4947 if (r->param.inet_network.is_ipv6) 4948 ccs_print_ipv6(buf, sizeof(buf), 4949 (const struct in6_addr *) address); 4950 else 4951 ccs_print_ipv4(buf, sizeof(buf), address); 4952 return ccs_supervisor(r, "network inet %s %s %s %u\n", 4953 ccs_proto_keyword[r->param.inet_network. 4954 protocol], 4955 ccs_socket_keyword[r->param.inet_network. 4956 operation], 4957 buf, r->param.inet_network.port); 4958 case CCS_TYPE_UNIX_ACL: 4959 return ccs_supervisor(r, "network unix %s %s %s\n", 4960 ccs_proto_keyword[r->param. 4961 unix_network.protocol], 4962 ccs_socket_keyword[r->param.unix_network. 4963 operation], 4964 r->param.unix_network.address->name); 4965 #endif 4966 #ifdef CONFIG_CCSECURITY_IPC 4967 case CCS_TYPE_SIGNAL_ACL: 4968 return ccs_supervisor(r, "ipc signal %d %s\n", 4969 r->param.signal.sig, 4970 r->param.signal.dest_pattern); 4971 #endif 4972 } 4973 return 0; 4974 } 4975 4976 /** 4977 * ccs_find_domain_by_qid - Get domain by query id. 4978 * 4979 * @serial: Query ID assigned by ccs_supervisor(). 4980 * 4981 * Returns pointer to "struct ccs_domain_info" if found, NULL otherwise. 4982 */ 4983 static struct ccs_domain_info *ccs_find_domain_by_qid(unsigned int serial) 4984 { 4985 struct ccs_query *ptr; 4986 struct ccs_domain_info *domain = NULL; 4987 spin_lock(&ccs_query_list_lock); 4988 list_for_each_entry(ptr, &ccs_query_list, list) { 4989 if (ptr->serial != serial) 4990 continue; 4991 domain = ptr->domain; 4992 break; 4993 } 4994 spin_unlock(&ccs_query_list_lock); 4995 return domain; 4996 } 4997 4998 /** 4999 * ccs_read_query - Read access requests which violated policy in enforcing mode. 5000 * 5001 * @head: Pointer to "struct ccs_io_buffer". 5002 * 5003 * Returns nothing. 5004 */ 5005 static void ccs_read_query(struct ccs_io_buffer *head) 5006 { 5007 struct list_head *tmp; 5008 unsigned int pos = 0; 5009 size_t len = 0; 5010 char *buf; 5011 if (head->r.w_pos) 5012 return; 5013 kfree(head->read_buf); 5014 head->read_buf = NULL; 5015 spin_lock(&ccs_query_list_lock); 5016 list_for_each(tmp, &ccs_query_list) { 5017 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5018 if (pos++ != head->r.query_index) 5019 continue; 5020 len = ptr->query_len; 5021 break; 5022 } 5023 spin_unlock(&ccs_query_list_lock); 5024 if (!len) { 5025 head->r.query_index = 0; 5026 return; 5027 } 5028 buf = kzalloc(len + 32, CCS_GFP_FLAGS); 5029 if (!buf) 5030 return; 5031 pos = 0; 5032 spin_lock(&ccs_query_list_lock); 5033 list_for_each(tmp, &ccs_query_list) { 5034 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5035 if (pos++ != head->r.query_index) 5036 continue; 5037 /* 5038 * Some query can be skipped because ccs_query_list 5039 * can change, but I don't care. 5040 */ 5041 if (len == ptr->query_len) 5042 snprintf(buf, len + 31, "Q%u-%hu\n%s", ptr->serial, 5043 ptr->retry, ptr->query); 5044 break; 5045 } 5046 spin_unlock(&ccs_query_list_lock); 5047 if (buf[0]) { 5048 head->read_buf = buf; 5049 head->r.w[head->r.w_pos++] = buf; 5050 head->r.query_index++; 5051 } else { 5052 kfree(buf); 5053 } 5054 } 5055 5056 /** 5057 * ccs_write_answer - Write the supervisor's decision. 5058 * 5059 * @head: Pointer to "struct ccs_io_buffer". 5060 * 5061 * Returns 0 on success, -EINVAL otherwise. 5062 */ 5063 static int ccs_write_answer(struct ccs_io_buffer *head) 5064 { 5065 char *data = head->write_buf; 5066 struct list_head *tmp; 5067 unsigned int serial; 5068 unsigned int answer; 5069 spin_lock(&ccs_query_list_lock); 5070 list_for_each(tmp, &ccs_query_list) { 5071 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5072 ptr->timer = 0; 5073 } 5074 spin_unlock(&ccs_query_list_lock); 5075 if (sscanf(data, "A%u=%u", &serial, &answer) != 2) 5076 return -EINVAL; 5077 spin_lock(&ccs_query_list_lock); 5078 list_for_each(tmp, &ccs_query_list) { 5079 struct ccs_query *ptr = list_entry(tmp, typeof(*ptr), list); 5080 if (ptr->serial != serial) 5081 continue; 5082 ptr->answer = (u8) answer; 5083 /* Remove from ccs_query_list. */ 5084 if (ptr->answer) { 5085 list_del(&ptr->list); 5086 INIT_LIST_HEAD(&ptr->list); 5087 } 5088 break; 5089 } 5090 spin_unlock(&ccs_query_list_lock); 5091 wake_up_all(&ccs_answer_wait); 5092 return 0; 5093 } 5094 5095 /** 5096 * ccs_read_version - Get version. 5097 * 5098 * @head: Pointer to "struct ccs_io_buffer". 5099 * 5100 * Returns nothing. 5101 */ 5102 static void ccs_read_version(struct ccs_io_buffer *head) 5103 { 5104 if (head->r.eof) 5105 return; 5106 ccs_set_string(head, "1.8.5"); 5107 head->r.eof = true; 5108 } 5109 5110 /** 5111 * ccs_update_stat - Update statistic counters. 5112 * 5113 * @index: Index for policy type. 5114 * 5115 * Returns nothing. 5116 */ 5117 static void ccs_update_stat(const u8 index) 5118 { 5119 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 5120 struct timeval tv; 5121 do_gettimeofday(&tv); 5122 /* 5123 * I don't use atomic operations because race condition is not fatal. 5124 */ 5125 ccs_stat_updated[index]++; 5126 ccs_stat_modified[index] = tv.tv_sec; 5127 #else 5128 /* 5129 * I don't use atomic operations because race condition is not fatal. 5130 */ 5131 ccs_stat_updated[index]++; 5132 ccs_stat_modified[index] = get_seconds(); 5133 #endif 5134 } 5135 5136 /** 5137 * ccs_read_stat - Read statistic data. 5138 * 5139 * @head: Pointer to "struct ccs_io_buffer". 5140 * 5141 * Returns nothing. 5142 */ 5143 static void ccs_read_stat(struct ccs_io_buffer *head) 5144 { 5145 u8 i; 5146 unsigned int total = 0; 5147 if (head->r.eof) 5148 return; 5149 for (i = 0; i < CCS_MAX_POLICY_STAT; i++) { 5150 ccs_io_printf(head, "Policy %-30s %10u", ccs_policy_headers[i], 5151 ccs_stat_updated[i]); 5152 if (ccs_stat_modified[i]) { 5153 struct ccs_time stamp; 5154 ccs_convert_time(ccs_stat_modified[i], &stamp); 5155 ccs_io_printf(head, " (Last: %04u/%02u/%02u " 5156 "%02u:%02u:%02u)", 5157 stamp.year, stamp.month, stamp.day, 5158 stamp.hour, stamp.min, stamp.sec); 5159 } 5160 ccs_set_lf(head); 5161 } 5162 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) { 5163 unsigned int used = ccs_memory_used[i]; 5164 total += used; 5165 ccs_io_printf(head, "Memory used by %-22s %10u", 5166 ccs_memory_headers[i], used); 5167 used = ccs_memory_quota[i]; 5168 if (used) 5169 ccs_io_printf(head, " (Quota: %10u)", used); 5170 ccs_set_lf(head); 5171 } 5172 ccs_io_printf(head, "Total memory used: %10u\n", 5173 total); 5174 head->r.eof = true; 5175 } 5176 5177 /** 5178 * ccs_write_stat - Set memory quota. 5179 * 5180 * @head: Pointer to "struct ccs_io_buffer". 5181 * 5182 * Returns 0. 5183 */ 5184 static int ccs_write_stat(struct ccs_io_buffer *head) 5185 { 5186 char *data = head->write_buf; 5187 u8 i; 5188 if (ccs_str_starts(&data, "Memory used by ")) 5189 for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) 5190 if (ccs_str_starts(&data, ccs_memory_headers[i])) { 5191 if (*data == ' ') 5192 data++; 5193 ccs_memory_quota[i] = 5194 simple_strtoul(data, NULL, 10); 5195 } 5196 return 0; 5197 } 5198 5199 /** 5200 * ccs_print_bprm - Print "struct linux_binprm" for auditing. 5201 * 5202 * @bprm: Pointer to "struct linux_binprm". 5203 * @dump: Pointer to "struct ccs_page_dump". 5204 * 5205 * Returns the contents of @bprm on success, NULL otherwise. 5206 * 5207 * This function uses kzalloc(), so caller must kfree() if this function 5208 * didn't return NULL. 5209 */ 5210 static char *ccs_print_bprm(struct linux_binprm *bprm, 5211 struct ccs_page_dump *dump) 5212 { 5213 static const int ccs_buffer_len = 4096 * 2; 5214 char *buffer = kzalloc(ccs_buffer_len, CCS_GFP_FLAGS); 5215 char *cp; 5216 char *last_start; 5217 int len; 5218 unsigned long pos = bprm->p; 5219 int offset = pos % PAGE_SIZE; 5220 int argv_count = bprm->argc; 5221 int envp_count = bprm->envc; 5222 bool truncated = false; 5223 if (!buffer) 5224 return NULL; 5225 len = snprintf(buffer, ccs_buffer_len - 1, "argv[]={ "); 5226 cp = buffer + len; 5227 if (!argv_count) { 5228 memmove(cp, "} envp[]={ ", 11); 5229 cp += 11; 5230 } 5231 last_start = cp; 5232 while (argv_count || envp_count) { 5233 if (!ccs_dump_page(bprm, pos, dump)) 5234 goto out; 5235 pos += PAGE_SIZE - offset; 5236 /* Read. */ 5237 while (offset < PAGE_SIZE) { 5238 const char *kaddr = dump->data; 5239 const unsigned char c = kaddr[offset++]; 5240 if (cp == last_start) 5241 *cp++ = '"'; 5242 if (cp >= buffer + ccs_buffer_len - 32) { 5243 /* Reserve some room for "..." string. */ 5244 truncated = true; 5245 } else if (c == '\\') { 5246 *cp++ = '\\'; 5247 *cp++ = '\\'; 5248 } else if (c > ' ' && c < 127) { 5249 *cp++ = c; 5250 } else if (!c) { 5251 *cp++ = '"'; 5252 *cp++ = ' '; 5253 last_start = cp; 5254 } else { 5255 *cp++ = '\\'; 5256 *cp++ = (c >> 6) + ''; 5257 *cp++ = ((c >> 3) & 7) + ''; 5258 *cp++ = (c & 7) + ''; 5259 } 5260 if (c) 5261 continue; 5262 if (argv_count) { 5263 if (--argv_count == 0) { 5264 if (truncated) { 5265 cp = last_start; 5266 memmove(cp, "... ", 4); 5267 cp += 4; 5268 } 5269 memmove(cp, "} envp[]={ ", 11); 5270 cp += 11; 5271 last_start = cp; 5272 truncated = false; 5273 } 5274 } else if (envp_count) { 5275 if (--envp_count == 0) { 5276 if (truncated) { 5277 cp = last_start; 5278 memmove(cp, "... ", 4); 5279 cp += 4; 5280 } 5281 } 5282 } 5283 if (!argv_count && !envp_count) 5284 break; 5285 } 5286 offset = 0; 5287 } 5288 *cp++ = '}'; 5289 *cp = '\0'; 5290 return buffer; 5291 out: 5292 snprintf(buffer, ccs_buffer_len - 1, "argv[]={ ... } envp[]= { ... }"); 5293 return buffer; 5294 } 5295 5296 /** 5297 * ccs_filetype - Get string representation of file type. 5298 * 5299 * @mode: Mode value for stat(). 5300 * 5301 * Returns file type string. 5302 */ 5303 static inline const char *ccs_filetype(const umode_t mode) 5304 { 5305 switch (mode & S_IFMT) { 5306 case S_IFREG: 5307 case 0: 5308 return ccs_condition_keyword[CCS_TYPE_IS_FILE]; 5309 case S_IFDIR: 5310 return ccs_condition_keyword[CCS_TYPE_IS_DIRECTORY]; 5311 case S_IFLNK: 5312 return ccs_condition_keyword[CCS_TYPE_IS_SYMLINK]; 5313 case S_IFIFO: 5314 return ccs_condition_keyword[CCS_TYPE_IS_FIFO]; 5315 case S_IFSOCK: 5316 return ccs_condition_keyword[CCS_TYPE_IS_SOCKET]; 5317 case S_IFBLK: 5318 return ccs_condition_keyword[CCS_TYPE_IS_BLOCK_DEV]; 5319 case S_IFCHR: 5320 return ccs_condition_keyword[CCS_TYPE_IS_CHAR_DEV]; 5321 } 5322 return "unknown"; /* This should not happen. */ 5323 } 5324 5325 /** 5326 * ccs_print_header - Get header line of audit log. 5327 * 5328 * @r: Pointer to "struct ccs_request_info". 5329 * 5330 * Returns string representation. 5331 * 5332 * This function uses kmalloc(), so caller must kfree() if this function 5333 * didn't return NULL. 5334 */ 5335 static char *ccs_print_header(struct ccs_request_info *r) 5336 { 5337 struct ccs_time stamp; 5338 struct ccs_obj_info *obj = r->obj; 5339 const u32 ccs_flags = ccs_current_flags(); 5340 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) 5341 const pid_t gpid = ccs_sys_getpid(); 5342 #else 5343 const pid_t gpid = task_pid_nr(current); 5344 #endif 5345 static const int ccs_buffer_len = 4096; 5346 char *buffer = kmalloc(ccs_buffer_len, CCS_GFP_FLAGS); 5347 int pos; 5348 u8 i; 5349 if (!buffer) 5350 return NULL; 5351 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 5352 { 5353 struct timeval tv; 5354 do_gettimeofday(&tv); 5355 ccs_convert_time(tv.tv_sec, &stamp); 5356 } 5357 #else 5358 ccs_convert_time(get_seconds(), &stamp); 5359 #endif 5360 pos = snprintf(buffer, ccs_buffer_len - 1, 5361 "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s " 5362 "granted=%s (global-pid=%u) task={ pid=%u ppid=%u " 5363 "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u " 5364 "fsuid=%u fsgid=%u type%s=execute_handler }", 5365 stamp.year, stamp.month, stamp.day, stamp.hour, 5366 stamp.min, stamp.sec, r->profile,