1 /* 2 * Copyright (c) 2013-2019, 2022 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 #ifndef __CONTENT_FILTER_H__ 25 #define __CONTENT_FILTER_H__ 26 27 #include <sys/param.h> 28 #include <sys/types.h> 29 #include <sys/_types/_timeval64.h> 30 #include <sys/socket.h> 31 #include <sys/syslog.h> 32 #include <netinet/in.h> 33 #include <stdint.h> 34 #include <corecrypto/ccsha2.h> 35 36 #ifdef BSD_KERNEL_PRIVATE 37 #include <sys/mbuf.h> 38 #include <sys/socketvar.h> 39 #endif /* BSD_KERNEL_PRIVATE */ 40 41 #ifndef XNU_KERNEL_PRIVATE 42 #include <TargetConditionals.h> 43 #endif 44 45 __BEGIN_DECLS 46 47 #ifdef PRIVATE 48 49 /* 50 * Kernel control name for an instance of a Content Filter 51 * Use CTLIOCGINFO to find out the corresponding kernel control id 52 * to be set in the sc_id field of sockaddr_ctl for connect(2) 53 * Note: the sc_unit is ephemeral 54 */ 55 #define CONTENT_FILTER_CONTROL_NAME "com.apple.content-filter" 56 57 /* 58 * Opaque socket identifier 59 */ 60 typedef uint64_t cfil_sock_id_t; 61 62 #define CFIL_SOCK_ID_NONE UINT64_MAX 63 64 65 /* 66 * CFIL_OPT_NECP_CONTROL_UNIT 67 * To set or get the NECP filter control unit for the kernel control socket 68 * The option level is SYSPROTO_CONTROL 69 */ 70 #define CFIL_OPT_NECP_CONTROL_UNIT 1 /* uint32_t */ 71 72 /* 73 * CFIL_OPT_GET_SOCKET_INFO 74 * To get information about a given socket that is being filtered. 75 */ 76 #define CFIL_OPT_GET_SOCKET_INFO 2 /* uint32_t */ 77 78 /* 79 * CFIL_OPT_PRESERVE_CONNECTIONS 80 * To set or get the preserve-connections setting for the filter 81 */ 82 #define CFIL_OPT_PRESERVE_CONNECTIONS 3 /* uint32_t */ 83 84 /* 85 * struct cfil_opt_sock_info 86 * 87 * Contains information about a socket that is being filtered. 88 */ 89 struct cfil_opt_sock_info { 90 cfil_sock_id_t cfs_sock_id; 91 int cfs_sock_family; /* e.g. PF_INET */ 92 int cfs_sock_type; /* e.g. SOCK_STREAM */ 93 int cfs_sock_protocol; /* e.g. IPPROTO_TCP */ 94 union sockaddr_in_4_6 cfs_local; 95 union sockaddr_in_4_6 cfs_remote; 96 pid_t cfs_pid; 97 pid_t cfs_e_pid; 98 pid_t cfs_r_pid; 99 uuid_t cfs_uuid; 100 uuid_t cfs_e_uuid; 101 uuid_t cfs_r_uuid; 102 }; 103 104 /* 105 * How many filter may be active simultaneously 106 */ 107 108 #define CFIL_MAX_FILTER_COUNT 8 109 110 /* 111 * Crypto Support 112 */ 113 #define CFIL_CRYPTO 1 114 #define CFIL_CRYPTO_SIGNATURE_SIZE 32 115 #define CFIL_CRYPTO_DATA_EVENT 1 116 117 typedef uint8_t cfil_crypto_key[CCSHA256_OUTPUT_SIZE]; 118 typedef uint8_t cfil_crypto_signature[CFIL_CRYPTO_SIGNATURE_SIZE]; 119 120 typedef struct cfil_crypto_state { 121 const struct ccdigest_info *digest_info; 122 cfil_crypto_key key; 123 } *cfil_crypto_state_t; 124 125 typedef struct cfil_crypto_data { 126 uuid_t flow_id; 127 u_int64_t sock_id; 128 u_int32_t direction; 129 union sockaddr_in_4_6 remote; 130 union sockaddr_in_4_6 local; 131 u_int32_t socketProtocol; 132 pid_t pid; 133 pid_t effective_pid; 134 pid_t responsible_pid; 135 uuid_t uuid; 136 uuid_t effective_uuid; 137 uuid_t responsible_uuid; 138 u_int64_t byte_count_in; 139 u_int64_t byte_count_out; 140 } *cfil_crypto_data_t; 141 142 /* 143 * Responsible pid/uuid support 144 */ 145 #define CFIL_RESPONSIBLE_PID_SUPPORT 1 146 147 /* 148 * Types of messages 149 * 150 * Event messages flow from kernel to user space while action 151 * messages flow in the reverse direction. 152 * A message in entirely represented by a packet sent or received 153 * on a Content Filter kernel control socket. 154 */ 155 #define CFM_TYPE_EVENT 1 /* message from kernel */ 156 #define CFM_TYPE_ACTION 2 /* message to kernel */ 157 158 /* 159 * Operations associated with events from kernel 160 */ 161 #define CFM_OP_SOCKET_ATTACHED 1 /* a socket has been attached */ 162 #define CFM_OP_SOCKET_CLOSED 2 /* a socket is being closed */ 163 #define CFM_OP_DATA_OUT 3 /* data being sent */ 164 #define CFM_OP_DATA_IN 4 /* data being received */ 165 #define CFM_OP_DISCONNECT_OUT 5 /* no more outgoing data */ 166 #define CFM_OP_DISCONNECT_IN 6 /* no more incoming data */ 167 #define CFM_OP_STATS 7 /* periodic stats report(s) */ 168 169 /* 170 * Operations associated with action from filter to kernel 171 */ 172 #define CFM_OP_DATA_UPDATE 16 /* update pass or peek offsets */ 173 #define CFM_OP_DROP 17 /* shutdown socket, no more data */ 174 #define CFM_OP_BLESS_CLIENT 18 /* mark a client flow as already filtered, passes a uuid */ 175 #define CFM_OP_SET_CRYPTO_KEY 19 /* assign client crypto key for message signing */ 176 177 /* 178 * struct cfil_msg_hdr 179 * 180 * Header common to all messages 181 */ 182 struct cfil_msg_hdr { 183 uint32_t cfm_len; /* total length */ 184 uint32_t cfm_version; 185 uint32_t cfm_type; 186 uint32_t cfm_op; 187 cfil_sock_id_t cfm_sock_id; 188 }; 189 190 #define CFM_VERSION_CURRENT 1 191 192 /* 193 * Connection Direction 194 */ 195 #define CFS_CONNECTION_DIR_IN 0 196 #define CFS_CONNECTION_DIR_OUT 1 197 198 #define CFS_REAL_AUDIT_TOKEN 1 199 200 #define CFS_MAX_DOMAIN_NAME_LENGTH 256 201 202 203 /* 204 * struct cfil_msg_sock_attached 205 * 206 * Information about a new socket being attached to the content filter 207 * 208 * Action: No reply is expected as this does not block the creation of the 209 * TCP/IP but timely action must be taken to avoid user noticeable delays. 210 * 211 * Valid Types: CFM_TYPE_EVENT 212 * 213 * Valid Op: CFM_OP_SOCKET_ATTACHED 214 */ 215 struct cfil_msg_sock_attached { 216 struct cfil_msg_hdr cfs_msghdr; 217 int cfs_sock_family; /* e.g. PF_INET */ 218 int cfs_sock_type; /* e.g. SOCK_STREAM */ 219 int cfs_sock_protocol; /* e.g. IPPROTO_TCP */ 220 int cfs_unused; /* padding */ 221 pid_t cfs_pid; 222 pid_t cfs_e_pid; 223 pid_t cfs_r_pid; 224 uuid_t cfs_uuid; 225 uuid_t cfs_e_uuid; 226 uuid_t cfs_r_uuid; 227 union sockaddr_in_4_6 cfs_src; 228 union sockaddr_in_4_6 cfs_dst; 229 int cfs_conn_dir; 230 unsigned int cfs_audit_token[8]; /* Must match audit_token_t */ 231 unsigned int cfs_real_audit_token[8]; /* Must match audit_token_t */ 232 cfil_crypto_signature cfs_signature; 233 uint32_t cfs_signature_length; 234 char cfs_remote_domain_name[CFS_MAX_DOMAIN_NAME_LENGTH]; 235 }; 236 237 /* 238 * CFIL data flags 239 */ 240 #define CFD_DATA_FLAG_IP_HEADER 0x00000001 /* Data includes IP header */ 241 #define CFIL_DATA_HAS_DELEGATED_PID 1 242 /* 243 * struct cfil_msg_data_event 244 * 245 * Event for the content fiter to act on a span of data 246 * A data span is described by a pair of offsets over the cumulative 247 * number of bytes sent or received on the socket. 248 * 249 * Action: The event must be acted upon but the filter may buffer 250 * data spans until it has enough content to make a decision. 251 * The action must be timely to avoid user noticeable delays. 252 * 253 * Valid Type: CFM_TYPE_EVENT 254 * 255 * Valid Ops: CFM_OP_DATA_OUT, CFM_OP_DATA_IN 256 */ 257 struct cfil_msg_data_event { 258 struct cfil_msg_hdr cfd_msghdr; 259 union sockaddr_in_4_6 cfc_src; 260 union sockaddr_in_4_6 cfc_dst; 261 uint64_t cfd_start_offset; 262 uint64_t cfd_end_offset; 263 cfil_crypto_signature cfd_signature; 264 uint32_t cfd_signature_length; 265 uint32_t cfd_flags; 266 pid_t cfd_delegated_pid; 267 unsigned int cfd_delegated_audit_token[8]; 268 /* Actual content data immediatly follows */ 269 }; 270 271 #define CFI_MAX_TIME_LOG_ENTRY 6 272 /* 273 * struct cfil_msg_sock_closed 274 * 275 * Information about a socket being closed to the content filter 276 * 277 * Action: No reply is expected as this does not block the closing of the 278 * TCP/IP. 279 * 280 * Valid Types: CFM_TYPE_EVENT 281 * 282 * Valid Op: CFM_OP_SOCKET_CLOSED 283 */ 284 struct cfil_msg_sock_closed { 285 struct cfil_msg_hdr cfc_msghdr; 286 struct timeval64 cfc_first_event; 287 uint32_t cfc_op_list_ctr; 288 uint32_t cfc_op_time[CFI_MAX_TIME_LOG_ENTRY]; /* time interval in microseconds since first event */ 289 unsigned char cfc_op_list[CFI_MAX_TIME_LOG_ENTRY]; 290 uint64_t cfc_byte_inbound_count; 291 uint64_t cfc_byte_outbound_count; 292 #define CFC_CLOSED_EVENT_LADDR 1 293 union sockaddr_in_4_6 cfc_laddr; 294 cfil_crypto_signature cfc_signature; 295 uint32_t cfc_signature_length; 296 } __attribute__((aligned(8))); 297 298 /* 299 * struct cfil_msg_stats_report 300 * 301 * Statistics report for flow(s). 302 * 303 * Action: No reply is expected. 304 * 305 * Valid Types: CFM_TYPE_EVENT 306 * 307 * Valid Op: CFM_OP_STATS 308 */ 309 struct cfil_msg_sock_stats { 310 cfil_sock_id_t cfs_sock_id; 311 uint64_t cfs_byte_inbound_count; 312 uint64_t cfs_byte_outbound_count; 313 union sockaddr_in_4_6 cfs_laddr; 314 } __attribute__((aligned(8))); 315 316 struct cfil_msg_stats_report { 317 struct cfil_msg_hdr cfr_msghdr; 318 uint32_t cfr_count; 319 struct cfil_msg_sock_stats cfr_stats[]; 320 } __attribute__((aligned(8))); 321 322 /* 323 * struct cfil_msg_action 324 * 325 * Valid Type: CFM_TYPE_ACTION 326 * 327 * Valid Ops: CFM_OP_DATA_UPDATE, CFM_OP_DROP 328 * 329 * For CFM_OP_DATA_UPDATE: 330 * 331 * cfa_in_pass_offset and cfa_out_pass_offset indicates how much data is 332 * allowed to pass. A zero value does not modify the corresponding pass offset. 333 * 334 * cfa_in_peek_offset and cfa_out_peek_offset lets the filter specify how much 335 * data it needs to make a decision: the kernel will deliver data up to that 336 * offset (if less than cfa_pass_offset it is ignored). Use CFM_MAX_OFFSET 337 * if you don't value the corresponding peek offset to be updated. 338 */ 339 struct cfil_msg_action { 340 struct cfil_msg_hdr cfa_msghdr; 341 uint64_t cfa_in_pass_offset; 342 uint64_t cfa_in_peek_offset; 343 uint64_t cfa_out_pass_offset; 344 uint64_t cfa_out_peek_offset; 345 uint32_t cfa_stats_frequency; // Statistics frequency in milliseconds 346 }; 347 348 /* 349 * struct cfil_msg_bless_client 350 * 351 * Marks a client UUID as already filtered at a higher level. 352 * 353 * Valid Type: CFM_TYPE_ACTION 354 * 355 * Valid Ops: CFM_OP_BLESS_CLIENT 356 */ 357 struct cfil_msg_bless_client { 358 struct cfil_msg_hdr cfb_msghdr; 359 uuid_t cfb_client_uuid; 360 }; 361 362 /* 363 * struct cfil_msg_set_crypto_key 364 * 365 * Filter assigning client crypto key to CFIL for message signing 366 * 367 * Valid Type: CFM_TYPE_ACTION 368 * 369 * Valid Ops: CFM_OP_SET_CRYPTO_KEY 370 */ 371 struct cfil_msg_set_crypto_key { 372 struct cfil_msg_hdr cfb_msghdr; 373 cfil_crypto_key crypto_key; 374 }; 375 376 #define CFM_MAX_OFFSET UINT64_MAX 377 378 /* 379 * Statistics retrieved via sysctl(3) 380 */ 381 struct cfil_filter_stat { 382 uint32_t cfs_len; 383 uint32_t cfs_filter_id; 384 uint32_t cfs_flags; 385 uint32_t cfs_sock_count; 386 uint32_t cfs_necp_control_unit; 387 }; 388 389 struct cfil_entry_stat { 390 uint32_t ces_len; 391 uint32_t ces_filter_id; 392 uint32_t ces_flags; 393 uint32_t ces_necp_control_unit; 394 struct timeval64 ces_last_event; 395 struct timeval64 ces_last_action; 396 struct cfe_buf_stat { 397 uint64_t cbs_pending_first; 398 uint64_t cbs_pending_last; 399 uint64_t cbs_ctl_first; 400 uint64_t cbs_ctl_last; 401 uint64_t cbs_pass_offset; 402 uint64_t cbs_peek_offset; 403 uint64_t cbs_peeked; 404 } ces_snd, ces_rcv; 405 }; 406 407 struct cfil_sock_stat { 408 uint32_t cfs_len; 409 int cfs_sock_family; 410 int cfs_sock_type; 411 int cfs_sock_protocol; 412 cfil_sock_id_t cfs_sock_id; 413 uint64_t cfs_flags; 414 pid_t cfs_pid; 415 pid_t cfs_e_pid; 416 uuid_t cfs_uuid; 417 uuid_t cfs_e_uuid; 418 struct cfi_buf_stat { 419 uint64_t cbs_pending_first; 420 uint64_t cbs_pending_last; 421 uint64_t cbs_pass_offset; 422 uint64_t cbs_inject_q_len; 423 } cfs_snd, cfs_rcv; 424 struct cfil_entry_stat ces_entries[CFIL_MAX_FILTER_COUNT]; 425 }; 426 427 /* 428 * Global statistics 429 */ 430 struct cfil_stats { 431 int32_t cfs_ctl_connect_ok; 432 int32_t cfs_ctl_connect_fail; 433 int32_t cfs_ctl_disconnect_ok; 434 int32_t cfs_ctl_disconnect_fail; 435 int32_t cfs_ctl_send_ok; 436 int32_t cfs_ctl_send_bad; 437 int32_t cfs_ctl_rcvd_ok; 438 int32_t cfs_ctl_rcvd_bad; 439 int32_t cfs_ctl_rcvd_flow_lift; 440 int32_t cfs_ctl_action_data_update; 441 int32_t cfs_ctl_action_drop; 442 int32_t cfs_ctl_action_bad_op; 443 int32_t cfs_ctl_action_bad_len; 444 445 int32_t cfs_sock_id_not_found; 446 447 int32_t cfs_cfi_alloc_ok; 448 int32_t cfs_cfi_alloc_fail; 449 450 int32_t cfs_sock_userspace_only; 451 int32_t cfs_sock_attach_in_vain; 452 int32_t cfs_sock_attach_already; 453 int32_t cfs_sock_attach_no_mem; 454 int32_t cfs_sock_attach_failed; 455 int32_t cfs_sock_attached; 456 int32_t cfs_sock_detached; 457 458 int32_t cfs_attach_event_ok; 459 int32_t cfs_attach_event_flow_control; 460 int32_t cfs_attach_event_fail; 461 462 int32_t cfs_closed_event_ok; 463 int32_t cfs_closed_event_flow_control; 464 int32_t cfs_closed_event_fail; 465 466 int32_t cfs_data_event_ok; 467 int32_t cfs_data_event_flow_control; 468 int32_t cfs_data_event_fail; 469 470 int32_t cfs_stats_event_ok; 471 int32_t cfs_stats_event_flow_control; 472 int32_t cfs_stats_event_fail; 473 474 int32_t cfs_disconnect_in_event_ok; 475 int32_t cfs_disconnect_out_event_ok; 476 int32_t cfs_disconnect_event_flow_control; 477 int32_t cfs_disconnect_event_fail; 478 479 int32_t cfs_ctl_q_not_started; 480 481 int32_t cfs_close_wait; 482 int32_t cfs_close_wait_timeout; 483 484 int32_t cfs_flush_in_drop; 485 int32_t cfs_flush_out_drop; 486 int32_t cfs_flush_in_close; 487 int32_t cfs_flush_out_close; 488 int32_t cfs_flush_in_free; 489 int32_t cfs_flush_out_free; 490 491 int32_t cfs_inject_q_nomem; 492 int32_t cfs_inject_q_nobufs; 493 int32_t cfs_inject_q_detached; 494 int32_t cfs_inject_q_in_fail; 495 int32_t cfs_inject_q_out_fail; 496 497 int32_t cfs_inject_q_in_retry; 498 int32_t cfs_inject_q_out_retry; 499 500 int32_t cfs_data_in_control; 501 int32_t cfs_data_in_oob; 502 int32_t cfs_data_out_control; 503 int32_t cfs_data_out_oob; 504 505 int64_t cfs_ctl_q_in_enqueued __attribute__((aligned(8))); 506 int64_t cfs_ctl_q_out_enqueued __attribute__((aligned(8))); 507 int64_t cfs_ctl_q_in_peeked __attribute__((aligned(8))); 508 int64_t cfs_ctl_q_out_peeked __attribute__((aligned(8))); 509 510 int64_t cfs_pending_q_in_enqueued __attribute__((aligned(8))); 511 int64_t cfs_pending_q_out_enqueued __attribute__((aligned(8))); 512 513 int64_t cfs_inject_q_in_enqueued __attribute__((aligned(8))); 514 int64_t cfs_inject_q_out_enqueued __attribute__((aligned(8))); 515 int64_t cfs_inject_q_in_passed __attribute__((aligned(8))); 516 int64_t cfs_inject_q_out_passed __attribute__((aligned(8))); 517 }; 518 #endif /* PRIVATE */ 519 520 #ifdef BSD_KERNEL_PRIVATE 521 522 #define M_SKIPCFIL M_PROTO5 523 524 extern uint32_t cfil_active_count; 525 /* 526 * Check if flows on socket should be filtered 527 */ 528 #define CFIL_DGRAM_HAS_FILTERED_FLOWS(so) ((so->so_flags & SOF_CONTENT_FILTER) && (so->so_flow_db != NULL)) 529 #define CFIL_DGRAM_FILTERED(so) (!IS_TCP(so) && (cfil_active_count > 0) && (CFIL_DGRAM_HAS_FILTERED_FLOWS(so) || necp_socket_get_content_filter_control_unit(so))) 530 531 extern int cfil_log_level; 532 533 #define CFIL_LOG(level, fmt, ...) \ 534 do { \ 535 if (cfil_log_level >= level) \ 536 printf("%s:%d " fmt "\n",\ 537 __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 538 } while (0) 539 540 541 extern void cfil_register_m_tag(void); 542 543 extern void cfil_init(void); 544 545 extern boolean_t cfil_filter_present(void); 546 extern boolean_t cfil_sock_connected_pending_verdict(struct socket *so); 547 extern boolean_t cfil_sock_is_dead(struct socket *so); 548 extern boolean_t cfil_sock_tcp_add_time_wait(struct socket *so); 549 extern errno_t cfil_sock_attach(struct socket *so, 550 struct sockaddr *local, struct sockaddr *remote, int dir); 551 extern errno_t cfil_sock_detach(struct socket *so); 552 553 extern int cfil_sock_data_out(struct socket *so, struct sockaddr *to, 554 struct mbuf *data, struct mbuf *control, 555 uint32_t flags, struct soflow_hash_entry *); 556 extern int cfil_sock_data_in(struct socket *so, struct sockaddr *from, 557 struct mbuf *data, struct mbuf *control, 558 uint32_t flags, struct soflow_hash_entry *); 559 560 extern int cfil_sock_shutdown(struct socket *so, int *how); 561 extern void cfil_sock_is_closed(struct socket *so); 562 extern void cfil_sock_notify_shutdown(struct socket *so, int how); 563 extern void cfil_sock_close_wait(struct socket *so); 564 565 extern boolean_t cfil_sock_data_pending(struct sockbuf *sb); 566 extern int cfil_sock_data_space(struct sockbuf *sb); 567 extern void cfil_sock_buf_update(struct sockbuf *sb); 568 569 extern cfil_sock_id_t cfil_sock_id_from_socket(struct socket *so); 570 extern cfil_sock_id_t cfil_sock_id_from_datagram_socket(struct socket *so, struct sockaddr *local, struct sockaddr *remote); 571 572 extern struct m_tag *cfil_dgram_get_socket_state(struct mbuf *m, uint32_t *state_change_cnt, 573 uint32_t *options, struct sockaddr **faddr, int *inp_flags); 574 extern boolean_t cfil_dgram_peek_socket_state(struct mbuf *m, int *inp_flags); 575 576 #endif /* BSD_KERNEL_PRIVATE */ 577 578 __END_DECLS 579 580 #endif /* __CONTENT_FILTER_H__ */ 581