xref: /xnu-11215.41.3/bsd/sys/ubc_internal.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 1999-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  *	File:	ubc.h
30  *	Author:	Umesh Vaishampayan [[email protected]]
31  *		05-Aug-1999	umeshv	Created.
32  *
33  *	Header file for Unified Buffer Cache.
34  *
35  */
36 
37 #ifndef _SYS_UBC_INTERNAL_H_
38 #define _SYS_UBC_INTERNAL_H_
39 
40 #include <sys/appleapiopts.h>
41 #include <sys/types.h>
42 #include <sys/kernel_types.h>
43 #include <sys/ucred.h>
44 #include <sys/vnode.h>
45 #include <sys/ubc.h>
46 #include <sys/mman.h>
47 #include <sys/codesign.h>
48 #include <sys/code_signing.h>
49 
50 #include <sys/cdefs.h>
51 
52 #include <kern/locks.h>
53 #include <mach/memory_object_types.h>
54 
55 #include <libkern/ptrauth_utils.h>
56 
57 #include <vm/vm_protos.h>
58 
59 
60 #define UBC_INFO_NULL   ((struct ubc_info *) 0)
61 
62 
63 extern struct zone      *ubc_info_zone;
64 
65 /*
66  * Maximum number of vfs clusters per vnode
67  */
68 #define MAX_CLUSTERS    CONFIG_MAX_CLUSTERS
69 
70 #define SPARSE_PUSH_LIMIT 4     /* limit on number of concurrent sparse pushes outside of the cl_lockw */
71                                 /* once we reach this limit, we'll hold the lock */
72 
73 struct cl_extent {
74 	daddr64_t       b_addr;
75 	daddr64_t       e_addr;
76 };
77 
78 struct cl_wextent {
79 	daddr64_t       b_addr;
80 	daddr64_t       e_addr;
81 	int             io_flags;
82 };
83 
84 struct cl_readahead {
85 	lck_mtx_t       cl_lockr;
86 	daddr64_t       cl_lastr;                       /* last block read by client */
87 	daddr64_t       cl_maxra;                       /* last block prefetched by the read ahead */
88 	int             cl_ralen;                       /* length of last prefetch */
89 };
90 
91 struct cl_writebehind {
92 	lck_mtx_t       cl_lockw;
93 	void    *       cl_scmap;                       /* pointer to sparse cluster map */
94 	off_t           cl_last_write;                  /* offset of the end of the last write */
95 	off_t           cl_seq_written;                 /* sequentially written bytes */
96 	int             cl_sparse_pushes;               /* number of pushes outside of the cl_lockw in progress */
97 	int             cl_sparse_wait;                 /* synchronous push is in progress */
98 	int             cl_number;                      /* number of packed write behind clusters currently valid */
99 	struct cl_wextent cl_clusters[MAX_CLUSTERS];    /* packed write behind clusters */
100 };
101 
102 struct cs_hash;
103 
104 uint8_t cs_hash_type(struct cs_hash const *);
105 
106 struct cs_blob {
107 	struct cs_blob  *csb_next;
108 	vnode_t         csb_vnode;
109 	void            *csb_ro_addr;
110 	__xnu_struct_group(cs_cpu_info, csb_cpu_info, {
111 		cpu_type_t      csb_cpu_type;
112 		cpu_subtype_t   csb_cpu_subtype;
113 	});
114 	__xnu_struct_group(cs_signer_info, csb_signer_info, {
115 		unsigned int    csb_flags;
116 		unsigned int    csb_signer_type;
117 	});
118 	off_t           csb_base_offset;        /* Offset of Mach-O binary in fat binary */
119 	off_t           csb_start_offset;       /* Blob coverage area start, from csb_base_offset */
120 	off_t           csb_end_offset;         /* Blob coverage area end, from csb_base_offset */
121 	vm_size_t       csb_mem_size;
122 	vm_offset_t     csb_mem_offset;
123 	void            *csb_mem_kaddr;
124 	unsigned char   csb_cdhash[CS_CDHASH_LEN];
125 	const struct cs_hash  *csb_hashtype;
126 #if CONFIG_SUPPLEMENTAL_SIGNATURES
127 	unsigned char   csb_linkage[CS_CDHASH_LEN];
128 	const struct cs_hash  *csb_linkage_hashtype;
129 #endif
130 	int             csb_hash_pageshift;
131 	int             csb_hash_firstlevel_pageshift;   /* First hash this many bytes, then hash the hashes together */
132 	const CS_CodeDirectory *csb_cd;
133 	const char      *csb_teamid;
134 #if CONFIG_SUPPLEMENTAL_SIGNATURES
135 	char            *csb_supplement_teamid;
136 #endif
137 	const CS_GenericBlob *csb_entitlements_blob;    /* raw blob, subrange of csb_mem_kaddr */
138 	const CS_GenericBlob *csb_der_entitlements_blob;    /* raw blob, subrange of csb_mem_kaddr */
139 
140 	/*
141 	 * OSEntitlements pointer setup by AMFI. This is PAC signed in addition to the
142 	 * cs_blob being within RO-memory to prevent modifications on the temporary stack
143 	 * variable used to setup the blob.
144 	 */
145 	void *XNU_PTRAUTH_SIGNED_PTR("cs_blob.csb_entitlements") csb_entitlements;
146 
147 	unsigned int    csb_reconstituted;      /* signature has potentially been modified after validation */
148 	__xnu_struct_group(cs_blob_platform_flags, csb_platform_flags, {
149 		/* The following two will be replaced by the csb_signer_type. */
150 		unsigned int    csb_platform_binary:1;
151 		unsigned int    csb_platform_path:1;
152 	});
153 
154 	/* Validation category used for TLE */
155 	unsigned int    csb_validation_category;
156 
157 #if CODE_SIGNING_MONITOR
158 	void *XNU_PTRAUTH_SIGNED_PTR("cs_blob.csb_csm_obj") csb_csm_obj;
159 	bool csb_csm_managed;
160 #endif
161 };
162 
163 /*
164  *	The following data structure keeps the information to associate
165  *	a vnode to the correspondig VM objects.
166  */
167 struct ubc_info {
168 	memory_object_t         ui_pager;       /* pager */
169 	memory_object_control_t ui_control;     /* VM control for the pager */
170 	vnode_t                 XNU_PTRAUTH_SIGNED_PTR("ubc_info.ui_vnode") ui_vnode;       /* vnode for this ubc_info */
171 	kauth_cred_t            ui_ucred;       /* holds credentials for NFS paging */
172 	off_t                   ui_size;        /* file size for the vnode */
173 	uint32_t                ui_flags;       /* flags */
174 	uint32_t                cs_add_gen;     /* generation count when csblob was validated */
175 
176 	struct  cl_readahead   *cl_rahead;      /* cluster read ahead context */
177 	struct  cl_writebehind *cl_wbehind;     /* cluster write behind context */
178 
179 	struct timespec         cs_mtime;       /* modify time of file when
180 	                                         *   first cs_blob was loaded */
181 	struct  cs_blob         * XNU_PTRAUTH_SIGNED_PTR("ubc_info.cs_blob") cs_blobs; /* for CODE SIGNING */
182 #if CONFIG_SUPPLEMENTAL_SIGNATURES
183 	struct  cs_blob         * cs_blob_supplement;/* supplemental blob (note that there can only be one supplement) */
184 #endif
185 #if CHECK_CS_VALIDATION_BITMAP
186 	void                    * XNU_PTRAUTH_SIGNED_PTR("ubc_info.cs_valid_bitmap") cs_valid_bitmap;     /* right now: used only for signed files on the read-only root volume */
187 	uint64_t                cs_valid_bitmap_size; /* Save original bitmap size in case the file size changes.
188 	                                               * In the future, we may want to reconsider changing the
189 	                                               * underlying bitmap to reflect the new file size changes.
190 	                                               */
191 #endif /* CHECK_CS_VALIDATION_BITMAP */
192 };
193 
194 /* Defines for ui_flags */
195 #define UI_NONE           0x00000000    /* none */
196 #define UI_HASPAGER       0x00000001    /* has a pager associated */
197 #define UI_INITED         0x00000002    /* newly initialized vnode */
198 #define UI_HASOBJREF      0x00000004    /* hold a reference on object */
199 #define UI_WASMAPPED      0x00000008    /* vnode was mapped */
200 #define UI_ISMAPPED       0x00000010    /* vnode is currently mapped */
201 #define UI_MAPBUSY        0x00000020    /* vnode is being mapped or unmapped */
202 #define UI_MAPWAITING     0x00000040    /* someone waiting for UI_MAPBUSY */
203 #define UI_MAPPEDWRITE    0x00000080    /* it's mapped with PROT_WRITE */
204 #define UI_CSBLOBINVALID  0x00000100    /* existing csblobs are invalid */
205 #define UI_WASMAPPEDWRITE 0x00000200    /* was mapped writable at some point */
206 
207 /*
208  * exported primitives for loadable file systems.
209  */
210 
211 __BEGIN_DECLS
212 
213 __private_extern__ int  ubc_umount(mount_t mp);
214 __private_extern__ void ubc_unmountall(void);
215 __private_extern__ memory_object_t ubc_getpager(vnode_t);
216 __private_extern__ void ubc_destroy_named(vnode_t vp, vm_object_destroy_reason_t reason);
217 
218 /* internal only */
219 __private_extern__ void cluster_release(struct ubc_info *);
220 __private_extern__ uint32_t cluster_throttle_io_limit(vnode_t, uint32_t *);
221 
222 
223 /* Flags for ubc_getobject() */
224 #define UBC_FLAGS_NONE          0x0000
225 #define UBC_HOLDOBJECT          0x0001
226 #define UBC_FOR_PAGEOUT         0x0002
227 
228 memory_object_control_t ubc_getobject(vnode_t, int);
229 
230 int     ubc_info_init(vnode_t);
231 int     ubc_info_init_withsize(vnode_t, off_t);
232 void    ubc_info_deallocate(struct ubc_info *);
233 
234 int     ubc_isinuse(vnode_t, int);
235 int     ubc_isinuse_locked(vnode_t, int, int);
236 
237 int     ubc_getcdhash(vnode_t, off_t, unsigned char *);
238 
239 /* code signing */
240 typedef enum __attribute__((enum_extensibility(closed), flag_enum)) : uint8_t {
241 	CS_BLOB_ADD_ALLOW_MAIN_BINARY = (1 << 0),
242 } cs_blob_add_flags_t;
243 
244 struct cs_blob;
245 void    cs_blob_require(struct cs_blob *, vnode_t);
246 int     ubc_cs_blob_add(
247 	vnode_t, uint32_t, cpu_type_t, cpu_subtype_t, off_t,
248 	vm_address_t *, vm_size_t, struct image_params *,
249 	int, struct cs_blob **, cs_blob_add_flags_t);
250 #if CONFIG_SUPPLEMENTAL_SIGNATURES
251 int     ubc_cs_blob_add_supplement(vnode_t, vnode_t, off_t, vm_address_t *, vm_size_t, struct cs_blob **);
252 #endif
253 struct cs_blob *ubc_get_cs_blobs(vnode_t);
254 #if CONFIG_SUPPLEMENTAL_SIGNATURES
255 struct cs_blob *ubc_get_cs_supplement(vnode_t);
256 #endif
257 void    ubc_get_cs_mtime(vnode_t, struct timespec *);
258 int     ubc_cs_getcdhash(vnode_t, off_t, unsigned char *);
259 kern_return_t ubc_cs_blob_allocate(vm_offset_t *, vm_size_t *);
260 void ubc_cs_blob_deallocate(vm_offset_t, vm_size_t);
261 boolean_t ubc_cs_is_range_codesigned(vnode_t, mach_vm_offset_t, mach_vm_size_t);
262 
263 kern_return_t   ubc_cs_validation_bitmap_allocate( vnode_t );
264 void            ubc_cs_validation_bitmap_deallocate( struct ubc_info * );
265 __END_DECLS
266 
267 
268 #endif  /* _SYS_UBC_INTERNAL_H_ */
269