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