/* * Copyright (c) 2006-2012 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * FILE: bootcaches.h * AUTH: Soren Spies (sspies) * DATE: "spring" 2006 * DESC: routines for dealing with bootcaches.plist data, bootstamps, etc * shared between kextcache and kextd * */ #ifndef __BOOTCACHES_H__ #define __BOOTCACHES_H__ #include #include #include #include #include // uuid_string_t #include // cache directories that we create (we also create kCSFDEPropertyCacheDir) #define kTSCacheDir "/System/Library/Caches/com.apple.bootstamps" #define kCacheDirMode 0755 // Sec reviewed #define kCacheFileMode 0644 // bootcaches.plist and keys #define kBootCachesPath "/usr/standalone/bootcaches.plist" #define kBootCachesDisabledPath "/usr/standalone/bootcaches-cachesonly.plist" #define kBCPreBootKey CFSTR("PreBootPaths") // dict #define kBCLabelKey CFSTR("DiskLabel") // ".disk_label" #define kBCBootersKey CFSTR("BooterPaths") // dict #define kBCEFIBooterKey CFSTR("EFIBooter") // "boot.efi" #define kBCOFBooterKey CFSTR("OFBooter") // "BootX" #define kBCPostBootKey CFSTR("PostBootPaths") // dict #define kBCMKextKey CFSTR("MKext") // dict #define kBCMKext2Key CFSTR("MKext2") // dict #define kBCKernelcacheV1Key CFSTR("Kernelcache v1.1")// dict #define kBCKernelcacheV2Key CFSTR("Kernelcache v1.2")// dict #define kBCKernelPathKey CFSTR("KernelPath") // path string #define kBCArchsKey CFSTR("Archs") // ar: ppc, i386 #define kBCExtensionsDirKey CFSTR("ExtensionsDir") // /S/L/E #define kBCPathKey CFSTR("Path") // path to cache // AdditionalPaths are optional w/PreBootPaths, required w/PostBootPaths #define kBCAdditionalPathsKey CFSTR("AdditionalPaths") // array #define kBCBootConfigKey CFSTR("BootConfig") // path to plist #define kBCEncryptedRootKey CFSTR("EncryptedRoot") // dict #define kBCCSFDEPropertyCacheKey CFSTR("EncryptedPropertyCache") // .wipekey #define kBCCSFDERootVolPropCacheKey CFSTR("RootVolumePropertyCache")//A_B only? #define kBCCSFDEDefResourcesDirKey CFSTR("DefaultResourcesDir") // EfiLoginUI #define kBCCSFDELocalizationSrcKey CFSTR("LocalizationSource") // EFI.fr/Res #define kBCCSFDELanguagesPrefKey CFSTR("LanguagesPref") // .Global... #define kBCCSFDELocRsrcsCacheKey CFSTR("LocalizedResourcesCache") // EFILogLocs typedef enum { kMkextCRCError = -1, kMkextCRCFound = 0, kMkextCRCNotFound = 1, } MkextCRCResult; // 6486172 points out that kextd ends up with a lot of these buffers // (especially w/multiple OS volumes). 8163405 adds BCPATH_MAX, etc. #define BCPATH_MAX 128 #define TSPATH_MAX (BCPATH_MAX + 1 + NCHARSUUID + 1 + BCPATH_MAX) #define NCHARSUUID (2*sizeof(uuid_t) + 5) // hex with 4 -'s and one NUL #define DEVMAXPATHSIZE 128 // xnu/devfs/devfsdefs.h: #define ROOTPATH_MAX (sizeof("/Volumes/") + NAME_MAX) typedef struct { char rpath[BCPATH_MAX]; // (relative) source path in root filesystem char tspath[TSPATH_MAX]; // shadow timestamp path tracking Apple_Boot[s] struct timeval tstamps[2]; // rpath's initial timestamp(s) } cachedPath; struct bootCaches { int cachefd; // Sec: file descriptor to validate data char bsdname[DEVMAXPATHSIZE]; // for passing to bless to get helpers char fsys_uuid[NCHARSUUID]; // optimized for cachedPaths (cf. 5114411, XX?) CFStringRef csfde_uuid; // encrypted volumes's LVF UUID char volname[NAME_MAX]; // for label generation char root[ROOTPATH_MAX]; // struct's paths relative to this root CFDictionaryRef cacheinfo; // raw BootCaches.plist data (for archs, etc) struct timespec bcTime; // cache the timestamp of bootcaches.plist char kernel[BCPATH_MAX]; // /Volumes/foo/mach_kernel (watch only) char exts[BCPATH_MAX]; // /S/L/Extensions (only a source) char locSource[BCPATH_MAX]; // only EFILogin.framework/Resources for now char locPref[BCPATH_MAX]; // /L/P/.GlabalPreferences unsigned nrps; // number of RPS paths in Apple_Boot cachedPath *rpspaths; // e.g. mkext, kernel, Boot.plist unsigned nmisc; // "other" files (non-critical) cachedPath *miscpaths; // e.g. icons, labels, etc cachedPath efibooter; // booters get their own paths cachedPath ofbooter; // (we have to bless them, etc) // pointers to special watched paths (stored in arrays above) cachedPath *kext_boot_cache_file; // -> mkext or kernelcache cachedPath *bootconfig; // -> .../L/Prefs/SC/com.apple.Boot.plist cachedPath *efidefrsrcs; // -> usr/standalone/i386/EfiLoginUI cachedPath *efiloccache; // -> ...Caches/../EFILoginLocalizations cachedPath *label; // -> .../S/L/CS/.disk_label (in miscPaths) cachedPath *erpropcache; // crypto metadata gets special treatment Boolean erpropTSOnly; // whether props expected in root fsys }; /* use sizeof() to get it the right bounds */ #undef TSPATH_MAX #undef BCPATH_MAX #undef ROOTPATH_MAX // inspectors Boolean hasBootRootBoots(struct bootCaches *caches, CFArrayRef *auxPartsCopy, CFArrayRef *dataPartsCopy, Boolean *isAPM); // Everything except vol_path is optional. // If specified, vol_bsd must point to at least DEVMAXPATHSIZE bytes. // If specified, vol_name must point to at least NAME_MAX bytes. // If no CoreStorage is detected and cslvf_uuid is non-NULL, // *cslvf_uuid will be set to NULL. int copyVolumeInfo(const char *vol_path, uuid_t *vol_uuid, CFStringRef *cslvf_uuid, char **vol_bsd, char **vol_name); // no CSFDE data => encContext = NULL, timeStamp = 0LL; int copyCSFDEInfo(CFStringRef uuidStr, CFDictionaryRef *encContext, time_t *timeStamp); // ctors / dtors struct bootCaches* readBootCaches(char *volRoot); // kextcache struct bootCaches* readBootCachesForDADisk(DADiskRef dadisk); // kextd void destroyCaches(struct bootCaches *caches); DADiskRef createDiskForMount(DASessionRef session, const char *mount); // "stat" a cachedPath, returning out-of-date & setting tstamp; logs errors // (currently only used in bootcaches.c) Boolean needsUpdate(char *root, cachedPath* cpath); // check all cached paths w/needsUpdate (exts/mkext not checked) Boolean needUpdates(struct bootCaches *caches, Boolean *rps, Boolean *booters, Boolean *misc, OSKextLogSpec oodLogSpec); // update the bootstamp files from the tstamps stored in the bootCaches struct #define kBCStampsUnlinkOnly 0 // updateStamps always unlinks #define kBCStampsApplyTimes 1 // apply stored timestamps int updateStamps(struct bootCaches *caches, int command); // check / rebuild kext caches needs rebuilding Boolean plistCachesNeedRebuild(const NXArchInfo * kernelArchInfo); Boolean check_kext_boot_cache_file( struct bootCaches * caches, const char * cache_path, const char * kernel_path); // build the mkext; waiting for the kextcache child if instructed int rebuild_kext_boot_cache_file( struct bootCaches *caches, Boolean wait, const char * cache_path, const char * kernel_path); // check/rebuild CSFDE caches Boolean check_csfde(struct bootCaches *caches); int rebuild_csfde_cache(struct bootCaches *caches); int writeCSFDEProps(int scopefd, CFDictionaryRef ectx, char *cspvbsd, char *dstpath); Boolean check_loccache(struct bootCaches *caches); int rebuild_loccache(struct bootCaches *caches); // diskarb helpers void _daDone(DADiskRef disk, DADissenterRef dissenter, void *ctx); int updateMount(mountpoint_t mount, uint32_t mntgoal); pid_t launch_rebuild_all(char * rootPath, Boolean force, Boolean wait); #endif /* __BOOTCACHES_H__ */