1/* 2 * Copyright (c) 2006-2012 Apple Inc. All rights reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * FILE: bootcaches.h 25 * AUTH: Soren Spies (sspies) 26 * DATE: "spring" 2006 27 * DESC: routines for dealing with bootcaches.plist data, bootstamps, etc 28 * shared between kextcache and kextd 29 * 30 */ 31 32#ifndef __BOOTCACHES_H__ 33#define __BOOTCACHES_H__ 34 35#include <CoreFoundation/CoreFoundation.h> 36#include <DiskArbitration/DiskArbitration.h> 37#include <sys/stat.h> 38#include <sys/time.h> 39#include <IOKit/kext/kextmanager_types.h> // uuid_string_t 40#include <mach-o/arch.h> 41 42#include "bootroot_internal.h" // includes bootroot.h 43 44// cache directories that we create (we also create kCSFDEPropertyCacheDir) 45#define kTSCacheDir "/System/Library/Caches/com.apple.bootstamps" 46#define kCacheDirMode 0755 // Sec reviewed 47#define kCacheFileMode 0644 48 49// bootcaches.plist and keys 50 51#define kBootCachesPath "/usr/standalone/bootcaches.plist" 52#define kBCPreBootKey CFSTR("PreBootPaths") // dict 53#define kBCLabelKey CFSTR("DiskLabel") // ".disk_label" 54#define kBCBootersKey CFSTR("BooterPaths") // dict 55#define kBCEFIBooterKey CFSTR("EFIBooter") // "boot.efi" 56#define kBCOFBooterKey CFSTR("OFBooter") // "BootX" 57#define kBCPostBootKey CFSTR("PostBootPaths") // dict 58#define kBCMKextKey CFSTR("MKext") // dict 59#define kBCMKext2Key CFSTR("MKext2") // dict 60#define kBCKernelcacheV1Key CFSTR("Kernelcache v1.1")// dict 61#define kBCKernelcacheV2Key CFSTR("Kernelcache v1.2")// dict 62#define kBCKernelcacheV3Key CFSTR("Kernelcache v1.3")// dict 63#define kBCKernelPathKey CFSTR("KernelPath") // m_k | kernel 64#define kBCPreferredCompressionKey CFSTR("Preferred Compression") // "lzvn" 65#if DEV_KERNEL_SUPPORT 66#define kBCKernelsDirKey CFSTR("KernelsDir") // S/L/Kernels 67#endif 68#define kBCArchsKey CFSTR("Archs") // ... i386 69#define kBCExtensionsDirKey CFSTR("ExtensionsDir") // /S/L/E, /L/E 70#define kBCPathKey CFSTR("Path") // ...kernelcache 71// AdditionalPaths are optional w/PreBootPaths, required w/PostBootPaths 72#define kBCAdditionalPathsKey CFSTR("AdditionalPaths") // array 73#define kBCBootConfigKey CFSTR("BootConfig") // bc.plist 74#define kBCEncryptedRootKey CFSTR("EncryptedRoot") // dict 75#define kBCCSFDEPropertyCacheKey CFSTR("EncryptedPropertyCache") // .wipekey 76#define kBCCSFDERootVolPropCacheKey CFSTR("RootVolumePropertyCache")//A_B only? 77#define kBCCSFDEDefResourcesDirKey CFSTR("DefaultResourcesDir") // EfiLoginUI 78#define kBCCSFDELocalizationSrcKey CFSTR("LocalizationSource") // EFI.fr/Res 79#define kBCCSFDELanguagesPrefKey CFSTR("LanguagesPref") // .GlobalPrefs 80#define kBCCSFDEBackgroundImageKey CFSTR("BackgroundImage") // desktop..png 81#define kBCCSFDELocRsrcsCacheKey CFSTR("LocalizedResourcesCache") // EFILocs 82 83 84typedef enum { 85 kMkextCRCError = -1, 86 kMkextCRCFound = 0, 87 kMkextCRCNotFound = 1, 88} MkextCRCResult; 89 90// 6486172 points out that kextd ends up with a lot of these buffers 91// (especially w/multiple OS vols). BCPATH_MAX (8163405) reduces the impact. 92#define NCHARSUUID (2*sizeof(uuid_t) + 5) // hex with 4 -'s and one NUL 93#define BCPATH_MAX 128 94#define TSPATH_MAX (BCPATH_MAX + 1 + NCHARSUUID + 1 + BCPATH_MAX) 95#define DEVMAXPATHSIZE 128 // xnu/devfs/devfsdefs.h: 96#define ROOTPATH_MAX (sizeof("/Volumes/") + NAME_MAX) 97 98typedef struct { 99 char rpath[BCPATH_MAX]; // (relative) source path in root filesystem 100 char tspath[TSPATH_MAX]; // shadow timestamp path tracking Apple_Boot[s] 101 struct timeval tstamps[2]; // rpath's initial timestamp(s) 102} cachedPath; 103 104struct bootCaches { 105 int cachefd; // Sec: file descriptor to validate data 106 char bsdname[DEVMAXPATHSIZE]; // for passing to bless to get helpers 107 uuid_string_t fsys_uuid; // optimized for cachedPaths (cf. 5114411, XX?) 108 CFStringRef csfde_uuid; // encrypted volumes's LVF UUID 109 char defLabel[NAME_MAX]; // defaults to volume name 110 char root[ROOTPATH_MAX]; // struct's paths relative to this root 111 CFDictionaryRef cacheinfo; // raw BootCaches.plist data (for archs, etc) 112 struct timespec bcTime; // cache the timestamp of bootcaches.plist 113 114 char kernelpath[BCPATH_MAX]; // path to kernel file (watch only) 115 // <= 10.9 - /Volumes/foo/mach_kernel 116 // > 10.9 - /Volumes/foo/System/Library/Kernels/kernel 117 int nexts; // number of extensions directory paths 118 char *exts; // null terminated extensions dir paths 119 char locSource[BCPATH_MAX]; // only EFILogin.framework/Resources for now 120 char locPref[BCPATH_MAX]; // /L/P/.GlobalPreferences 121 char bgImage[BCPATH_MAX]; // /L/Caches/com.apple.desktop.admin.png 122 unsigned nrps; // number of RPS paths in Apple_Boot 123 cachedPath *rpspaths; // e.g. mkext, kernel, Boot.plist 124 unsigned nmisc; // "other" files (non-critical) 125 cachedPath *miscpaths; // e.g. icons, labels, etc 126 cachedPath efibooter; // booters get their own paths 127 cachedPath ofbooter; // (we have to bless them, etc) 128 129 // pointers to special watched paths (stored in arrays above) 130 cachedPath *kext_boot_cache_file; // -> kernelcache 131 cachedPath *bootconfig; // -> .../L/Prefs/SC/com.apple.Boot.plist 132 cachedPath *efidefrsrcs; // -> usr/standalone/i386/EfiLoginUI 133 cachedPath *efiloccache; // -> ...Caches/../EFILoginLocalizations 134 cachedPath *label; // -> .../S/L/CS/.disk_label (in miscPaths) 135 cachedPath *erpropcache; // crypto metadata gets special treatment 136 Boolean erpropTSOnly; // whether props expected in root fsys 137#if DEV_KERNEL_SUPPORT 138 int kernelsCount; // count of valid kernels in /System/Library/Kernels 139 // This will be 0 for volumes that do not support 140 // /System/Library/Kernels/. 141 int nekcp; // number of extraKernelCachePaths 142 cachedPath *extraKernelCachePaths; // kernelcache files with suffix, may be NULL 143#endif 144}; 145/* use sizeof() to get it the right bounds */ 146#undef TSPATH_MAX 147#undef BCPATH_MAX 148#undef ROOTPATH_MAX 149 150// check and tweak Boot!=Root status 151Boolean hasBootRootBoots(struct bootCaches *caches, CFArrayRef *auxPartsCopy, 152 CFArrayRef *dataPartsCopy, Boolean *isAPM); 153Boolean notBRDefault(const char *mount, const char *subdir); 154int markNotBRDefault(int scopefd, const char *mount, const char* subdir, 155 Boolean marking); 156 157// Everything except vol_path is optional. 158// If specified, vol_bsd must point to at least DEVMAXPATHSIZE bytes. 159// If specified, vol_name must point to at least NAME_MAX bytes. 160// If no CoreStorage is detected and cslvf_uuid is non-NULL, 161// *cslvf_uuid will be set to NULL. 162int copyVolumeInfo(const char *vol_path, uuid_t *vol_uuid, 163 CFStringRef *cslvf_uuid, char vol_bsd[DEVMAXPATHSIZE], 164 char vol_name[NAME_MAX]); 165 166// no CSFDE data => encContext = NULL, timeStamp = 0LL; 167int copyCSFDEInfo(CFStringRef uuidStr, CFDictionaryRef *encContext, 168 time_t *timeStamp); 169 170/* ctors / dtors */ 171// for kextcache 172struct bootCaches* readBootCaches(char *volRoot, BRUpdateOpts_t opts); 173// and kextd 174struct bootCaches* readBootCachesForDADisk(DADiskRef dadisk); // kextd 175// (Warning: these will create S/L/Caches/bootstamps if missing.) 176 177void destroyCaches(struct bootCaches *caches); 178DADiskRef createDiskForMount(DASessionRef session, const char *mount); 179 180// Check all cached paths vs. bootstamps 181Boolean needUpdates(struct bootCaches *caches, BRUpdateOpts_t opts, 182 Boolean *rps, Boolean *booters, Boolean *misc, 183 OSKextLogSpec oodLogSpec); 184 185/* When copying non-default content to a helper partition, 186 taintDefaultStamps() finds and taints any online volumes that own the 187 helper. Once tainted, kextcache -u (called through Disk Management 188 by Startup Disk and the Installer) will notice that the helper contents 189 need to be replaced and will restore the volume and helper back to the 190 default configuration. kextd ignores the taint in its checks, but if 191 something else changes, the kextcache -u launched by kextd *will* 192 notice the taint and copy everything instead of only what changed. */ 193int taintDefaultStamps(CFStringRef targetBSD); 194 195// update the bootstamp files from the tstamps stored in the bootCaches struct 196#define kBCStampsUnlinkOnly 0 // updateStamps always unlinks 197#define kBCStampsApplyTimes 1 // apply stored timestamps 198int updateStamps(struct bootCaches *caches, int command); 199 200// check / rebuild kext caches needs rebuilding 201Boolean plistCachesNeedRebuild(const NXArchInfo * kernelArchInfo); 202Boolean check_kext_boot_cache_file( 203 struct bootCaches * caches, 204 const char * cache_path, 205 const char * kernel_path); 206// build the mkext; waiting for the kextcache child if instructed 207int rebuild_kext_boot_cache_file( 208 struct bootCaches *caches, 209 Boolean wait, 210 const char * cache_path, 211 const char * kernel_file); 212 213// check/rebuild CSFDE caches 214Boolean check_csfde(struct bootCaches *caches); 215int rebuild_csfde_cache(struct bootCaches *caches); 216int writeCSFDEProps(int scopefd, CFDictionaryRef ectx, 217 char *cspvbsd, char *dstpath); 218Boolean check_loccache(struct bootCaches *caches); 219int rebuild_loccache(struct bootCaches *caches); 220 221// diskarb helpers 222void _daDone(DADiskRef disk, DADissenterRef dissenter, void *ctx); 223int updateMount(mountpoint_t mount, uint32_t mntgoal); 224 225 226pid_t launch_rebuild_all(char * rootPath, Boolean force, Boolean wait); 227 228#endif /* __BOOTCACHES_H__ */ 229 230