xref: /xnu-11215.61.5/bsd/net/content_filter.h (revision 4f1223e81cd707a65cc109d0b8ad6653699da3c4)
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