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