/ duct-tape / xnu / bsd / net / content_filter.h
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__ */