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