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