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