xref: /xnu-8020.140.41/bsd/sys/ubc_internal.h (revision 27b03b360a988dfd3dfdf34262bb0042026747cc) !
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 
49 #include <sys/cdefs.h>
50 
51 #include <kern/locks.h>
52 #include <mach/memory_object_types.h>
53 
54 #include <libkern/ptrauth_utils.h>
55 
56 #define UBC_INFO_NULL   ((struct ubc_info *) 0)
57 
58 
59 extern struct zone      *ubc_info_zone;
60 
61 /*
62  * Maximum number of vfs clusters per vnode
63  */
64 #define MAX_CLUSTERS    CONFIG_MAX_CLUSTERS
65 
66 #define SPARSE_PUSH_LIMIT 4     /* limit on number of concurrent sparse pushes outside of the cl_lockw */
67                                 /* once we reach this limit, we'll hold the lock */
68 
69 struct cl_extent {
70 	daddr64_t       b_addr;
71 	daddr64_t       e_addr;
72 };
73 
74 struct cl_wextent {
75 	daddr64_t       b_addr;
76 	daddr64_t       e_addr;
77 	int             io_flags;
78 };
79 
80 struct cl_readahead {
81 	lck_mtx_t       cl_lockr;
82 	daddr64_t       cl_lastr;                       /* last block read by client */
83 	daddr64_t       cl_maxra;                       /* last block prefetched by the read ahead */
84 	int             cl_ralen;                       /* length of last prefetch */
85 };
86 
87 struct cl_writebehind {
88 	lck_mtx_t       cl_lockw;
89 	void    *       cl_scmap;                       /* pointer to sparse cluster map */
90 	off_t           cl_last_write;                  /* offset of the end of the last write */
91 	off_t           cl_seq_written;                 /* sequentially written bytes */
92 	int             cl_sparse_pushes;               /* number of pushes outside of the cl_lockw in progress */
93 	int             cl_sparse_wait;                 /* synchronous push is in progress */
94 	int             cl_number;                      /* number of packed write behind clusters currently valid */
95 	struct cl_wextent cl_clusters[MAX_CLUSTERS];    /* packed write behind clusters */
96 };
97 
98 struct cs_hash;
99 
100 uint8_t cs_hash_type(struct cs_hash const *);
101 
102 struct cs_blob {
103 	struct cs_blob  *csb_next;
104 	vnode_t         csb_vnode;
105 	void            *csb_ro_addr;
106 	__xnu_struct_group(cs_cpu_info, csb_cpu_info, {
107 		cpu_type_t      csb_cpu_type;
108 		cpu_subtype_t   csb_cpu_subtype;
109 	});
110 	__xnu_struct_group(cs_signer_info, csb_signer_info, {
111 		unsigned int    csb_flags;
112 		unsigned int    csb_signer_type;
113 	});
114 	off_t           csb_base_offset;        /* Offset of Mach-O binary in fat binary */
115 	off_t           csb_start_offset;       /* Blob coverage area start, from csb_base_offset */
116 	off_t           csb_end_offset;         /* Blob coverage area end, from csb_base_offset */
117 	vm_size_t       csb_mem_size;
118 	vm_offset_t     csb_mem_offset;
119 	void            *csb_mem_kaddr;
120 	unsigned char   csb_cdhash[CS_CDHASH_LEN];
121 	const struct cs_hash  *csb_hashtype;
122 #if CONFIG_SUPPLEMENTAL_SIGNATURES
123 	unsigned char   csb_linkage[CS_CDHASH_LEN];
124 	const struct cs_hash  *csb_linkage_hashtype;
125 #endif
126 	int             csb_hash_pageshift;
127 	int             csb_hash_firstlevel_pageshift;   /* First hash this many bytes, then hash the hashes together */
128 	const CS_CodeDirectory *csb_cd;
129 	const char      *csb_teamid;
130 #if CONFIG_SUPPLEMENTAL_SIGNATURES
131 	char            *csb_supplement_teamid;
132 #endif
133 	const CS_GenericBlob *csb_entitlements_blob;    /* raw blob, subrange of csb_mem_kaddr */
134 	const CS_GenericBlob *csb_der_entitlements_blob;    /* raw blob, subrange of csb_mem_kaddr */
135 	void *          csb_entitlements;       /* The entitlements as an OSEntitlements object */
136 	unsigned int    csb_reconstituted;      /* signature has potentially been modified after validation */
137 	__xnu_struct_group(cs_blob_platform_flags, csb_platform_flags, {
138 		/* The following two will be replaced by the csb_signer_type. */
139 		unsigned int    csb_platform_binary:1;
140 		unsigned int    csb_platform_path:1;
141 	});
142 
143 
144 	vm_address_t    profile_kaddr;
145 	vm_size_t       profile_allocation_size;
146 };
147 
148 /*
149  *	The following data structure keeps the information to associate
150  *	a vnode to the correspondig VM objects.
151  */
152 struct ubc_info {
153 	memory_object_t         ui_pager;       /* pager */
154 	memory_object_control_t ui_control;     /* VM control for the pager */
155 	vnode_t                 XNU_PTRAUTH_SIGNED_PTR("ubc_info.ui_vnode") ui_vnode;       /* vnode for this ubc_info */
156 	kauth_cred_t            ui_ucred;       /* holds credentials for NFS paging */
157 	off_t                   ui_size;        /* file size for the vnode */
158 	uint32_t                ui_flags;       /* flags */
159 	uint32_t                cs_add_gen;     /* generation count when csblob was validated */
160 
161 	struct  cl_readahead   *cl_rahead;      /* cluster read ahead context */
162 	struct  cl_writebehind *cl_wbehind;     /* cluster write behind context */
163 
164 	struct timespec         cs_mtime;       /* modify time of file when
165 	                                         *   first cs_blob was loaded */
166 	struct  cs_blob         * cs_blobs; /* for CODE SIGNING */
167 #if CONFIG_SUPPLEMENTAL_SIGNATURES
168 	struct  cs_blob         * cs_blob_supplement;/* supplemental blob (note that there can only be one supplement) */
169 #endif
170 #if CHECK_CS_VALIDATION_BITMAP
171 	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 */
172 	uint64_t                cs_valid_bitmap_size; /* Save original bitmap size in case the file size changes.
173 	                                               * In the future, we may want to reconsider changing the
174 	                                               * underlying bitmap to reflect the new file size changes.
175 	                                               */
176 #endif /* CHECK_CS_VALIDATION_BITMAP */
177 };
178 
179 /* Defines for ui_flags */
180 #define UI_NONE         0x00000000      /* none */
181 #define UI_HASPAGER     0x00000001      /* has a pager associated */
182 #define UI_INITED       0x00000002      /* newly initialized vnode */
183 #define UI_HASOBJREF    0x00000004      /* hold a reference on object */
184 #define UI_WASMAPPED    0x00000008      /* vnode was mapped */
185 #define UI_ISMAPPED     0x00000010      /* vnode is currently mapped */
186 #define UI_MAPBUSY      0x00000020      /* vnode is being mapped or unmapped */
187 #define UI_MAPWAITING   0x00000040      /* someone waiting for UI_MAPBUSY */
188 #define UI_MAPPEDWRITE  0x00000080      /* it's mapped with PROT_WRITE */
189 
190 /*
191  * exported primitives for loadable file systems.
192  */
193 
194 __BEGIN_DECLS
195 
196 __private_extern__ int  ubc_umount(mount_t mp);
197 __private_extern__ void ubc_unmountall(void);
198 __private_extern__ memory_object_t ubc_getpager(vnode_t);
199 __private_extern__ void ubc_destroy_named(vnode_t);
200 
201 /* internal only */
202 __private_extern__ void cluster_release(struct ubc_info *);
203 __private_extern__ uint32_t cluster_throttle_io_limit(vnode_t, uint32_t *);
204 
205 
206 /* Flags for ubc_getobject() */
207 #define UBC_FLAGS_NONE          0x0000
208 #define UBC_HOLDOBJECT          0x0001
209 #define UBC_FOR_PAGEOUT         0x0002
210 
211 memory_object_control_t ubc_getobject(vnode_t, int);
212 
213 int     ubc_info_init(vnode_t);
214 int     ubc_info_init_withsize(vnode_t, off_t);
215 void    ubc_info_deallocate(struct ubc_info *);
216 
217 int     ubc_isinuse(vnode_t, int);
218 int     ubc_isinuse_locked(vnode_t, int, int);
219 
220 int     ubc_getcdhash(vnode_t, off_t, unsigned char *);
221 
222 /* code signing */
223 struct cs_blob;
224 void    cs_blob_require(struct cs_blob *, vnode_t);
225 int     ubc_cs_blob_add(vnode_t, uint32_t, cpu_type_t, cpu_subtype_t, off_t, vm_address_t *, vm_size_t, struct image_params *, int, struct cs_blob **);
226 #if CONFIG_SUPPLEMENTAL_SIGNATURES
227 int     ubc_cs_blob_add_supplement(vnode_t, vnode_t, off_t, vm_address_t *, vm_size_t, struct cs_blob **);
228 #endif
229 struct cs_blob *ubc_get_cs_blobs(vnode_t);
230 #if CONFIG_SUPPLEMENTAL_SIGNATURES
231 struct cs_blob *ubc_get_cs_supplement(vnode_t);
232 #endif
233 void    ubc_get_cs_mtime(vnode_t, struct timespec *);
234 int     ubc_cs_getcdhash(vnode_t, off_t, unsigned char *);
235 kern_return_t ubc_cs_blob_allocate(vm_offset_t *, vm_size_t *);
236 void ubc_cs_blob_deallocate(vm_offset_t, vm_size_t);
237 boolean_t ubc_cs_is_range_codesigned(vnode_t, mach_vm_offset_t, mach_vm_size_t);
238 
239 kern_return_t   ubc_cs_validation_bitmap_allocate( vnode_t );
240 void            ubc_cs_validation_bitmap_deallocate( struct ubc_info * );
241 __END_DECLS
242 
243 
244 #endif  /* _SYS_UBC_INTERNAL_H_ */
245