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 kBootCachesDisabledPath "/usr/standalone/bootcaches-cachesonly.plist"
53#define kBCPreBootKey               CFSTR("PreBootPaths")    // dict
54#define kBCLabelKey                 CFSTR("DiskLabel")       // ".disk_label"
55#define kBCBootersKey               CFSTR("BooterPaths")     // dict
56#define kBCEFIBooterKey             CFSTR("EFIBooter")       // "boot.efi"
57#define kBCOFBooterKey              CFSTR("OFBooter")        // "BootX"
58#define kBCPostBootKey              CFSTR("PostBootPaths")   // dict
59#define kBCMKextKey                 CFSTR("MKext")           // dict
60#define kBCMKext2Key                CFSTR("MKext2")          // dict
61#define kBCKernelcacheV1Key         CFSTR("Kernelcache v1.1")// dict
62#define kBCKernelcacheV2Key         CFSTR("Kernelcache v1.2")// dict
63#define kBCKernelcacheV3Key         CFSTR("Kernelcache v1.3")// dict
64#define kBCKernelPathKey            CFSTR("KernelPath")      // path string
65#define kBCArchsKey                 CFSTR("Archs")           //   ar: ppc, i386
66#define kBCExtensionsDirKey         CFSTR("ExtensionsDir")   //   ar: /S/L/E & /L/E
67#define kBCPathKey                  CFSTR("Path")            //   path to cache
68// AdditionalPaths are optional w/PreBootPaths, required w/PostBootPaths
69#define kBCAdditionalPathsKey       CFSTR("AdditionalPaths") // array
70#define kBCBootConfigKey            CFSTR("BootConfig")      // path to plist
71#define kBCEncryptedRootKey         CFSTR("EncryptedRoot")   // dict
72#define kBCCSFDEPropertyCacheKey    CFSTR("EncryptedPropertyCache") // .wipekey
73#define kBCCSFDERootVolPropCacheKey CFSTR("RootVolumePropertyCache")//A_B only?
74#define kBCCSFDEDefResourcesDirKey  CFSTR("DefaultResourcesDir") // EfiLoginUI
75#define kBCCSFDELocalizationSrcKey  CFSTR("LocalizationSource")  // EFI.fr/Res
76#define kBCCSFDELanguagesPrefKey    CFSTR("LanguagesPref")  // .Global...
77#define kBCCSFDELocRsrcsCacheKey    CFSTR("LocalizedResourcesCache") // EFILogLocs
78
79
80typedef enum {
81    kMkextCRCError = -1,
82    kMkextCRCFound = 0,
83    kMkextCRCNotFound = 1,
84} MkextCRCResult;
85
86// 6486172 points out that kextd ends up with a lot of these buffers
87// (especially w/multiple OS vols).  BCPATH_MAX (8163405) reduces the impact.
88#define NCHARSUUID      (2*sizeof(uuid_t) + 5)  // hex with 4 -'s and one NUL
89#define BCPATH_MAX      128
90#define TSPATH_MAX      (BCPATH_MAX + 1 + NCHARSUUID + 1 + BCPATH_MAX)
91#define DEVMAXPATHSIZE  128                     // xnu/devfs/devfsdefs.h:
92#define ROOTPATH_MAX    (sizeof("/Volumes/") + NAME_MAX)
93
94typedef struct {
95    char rpath[BCPATH_MAX];     // (relative) source path in root filesystem
96    char tspath[TSPATH_MAX];    // shadow timestamp path tracking Apple_Boot[s]
97    struct timeval tstamps[2];  // rpath's initial timestamp(s)
98} cachedPath;
99
100struct bootCaches {
101    int cachefd;                // Sec: file descriptor to validate data
102    char bsdname[DEVMAXPATHSIZE]; // for passing to bless to get helpers
103    uuid_string_t fsys_uuid;    // optimized for cachedPaths (cf. 5114411, XX?)
104    CFStringRef csfde_uuid;     // encrypted volumes's LVF UUID
105    char defLabel[NAME_MAX];    // defaults to volume name
106    char root[ROOTPATH_MAX];    // struct's paths relative to this root
107    CFDictionaryRef cacheinfo;  // raw BootCaches.plist data (for archs, etc)
108    struct timespec bcTime;     // cache the timestamp of bootcaches.plist
109
110    char kernel[BCPATH_MAX];    // /Volumes/foo/mach_kernel (watch only)
111    int  nexts;                 // number of extensions directory paths
112    char *exts;                 // null terminated extensions dir paths
113    char locSource[BCPATH_MAX]; // only EFILogin.framework/Resources for now
114    char locPref[BCPATH_MAX];   // /L/P/.GlabalPreferences
115    unsigned nrps;              // number of RPS paths in Apple_Boot
116    cachedPath *rpspaths;       // e.g. mkext, kernel, Boot.plist
117    unsigned nmisc;             // "other" files (non-critical)
118    cachedPath *miscpaths;      // e.g. icons, labels, etc
119    cachedPath efibooter;       // booters get their own paths
120    cachedPath ofbooter;        // (we have to bless them, etc)
121
122    // pointers to special watched paths (stored in arrays above)
123    cachedPath *kext_boot_cache_file;     // -> mkext or kernelcache
124    cachedPath *bootconfig;     // -> .../L/Prefs/SC/com.apple.Boot.plist
125    cachedPath *efidefrsrcs;    // -> usr/standalone/i386/EfiLoginUI
126    cachedPath *efiloccache;    // -> ...Caches/../EFILoginLocalizations
127    cachedPath *label;          // -> .../S/L/CS/.disk_label (in miscPaths)
128    cachedPath *erpropcache;    // crypto metadata gets special treatment
129    Boolean erpropTSOnly;       // whether props expected in root fsys
130};
131/* use sizeof() to get it the right bounds */
132#undef TSPATH_MAX
133#undef BCPATH_MAX
134#undef ROOTPATH_MAX
135
136// inspectors
137Boolean hasBootRootBoots(struct bootCaches *caches, CFArrayRef *auxPartsCopy,
138                         CFArrayRef *dataPartsCopy, Boolean *isAPM);
139// Everything except vol_path is optional.
140// If specified, vol_bsd must point to at least DEVMAXPATHSIZE bytes.
141// If specified, vol_name must point to at least NAME_MAX bytes.
142// If no CoreStorage is detected and cslvf_uuid is non-NULL,
143// *cslvf_uuid will be set to NULL.
144int copyVolumeInfo(const char *vol_path, uuid_t *vol_uuid,
145                   CFStringRef *cslvf_uuid, char vol_bsd[DEVMAXPATHSIZE],
146                   char vol_name[NAME_MAX]);
147// no CSFDE data => encContext = NULL, timeStamp = 0LL;
148int copyCSFDEInfo(CFStringRef uuidStr, CFDictionaryRef *encContext,
149                   time_t *timeStamp);
150
151/* ctors / dtors */
152// for kextcache
153struct bootCaches* readBootCaches(char *volRoot, BRUpdateOpts_t opts);
154// and kextd
155struct bootCaches* readBootCachesForDADisk(DADiskRef dadisk);   // kextd
156
157void destroyCaches(struct bootCaches *caches);
158DADiskRef createDiskForMount(DASessionRef session, const char *mount);
159
160// "stat" a cachedPath, returning out-of-date & setting tstamp; logs errors
161// (currently only used in bootcaches.c)
162Boolean needsUpdate(char *root, cachedPath* cpath);
163// check all cached paths w/needsUpdate (exts/mkext not checked)
164Boolean needUpdates(struct bootCaches *caches, Boolean *rps,
165                    Boolean *booters, Boolean *misc, OSKextLogSpec oodLogSpec);
166
167// update the bootstamp files from the tstamps stored in the bootCaches struct
168#define kBCStampsUnlinkOnly 0           // updateStamps always unlinks
169#define kBCStampsApplyTimes 1           // apply stored timestamps
170int updateStamps(struct bootCaches *caches, int command);
171
172// check / rebuild kext caches needs rebuilding
173Boolean plistCachesNeedRebuild(const NXArchInfo * kernelArchInfo);
174Boolean check_kext_boot_cache_file(
175    struct bootCaches * caches,
176    const char * cache_path,
177    const char * kernel_path);
178// build the mkext; waiting for the kextcache child if instructed
179int rebuild_kext_boot_cache_file(
180    struct bootCaches *caches,
181    Boolean wait,
182    const char * cache_path,
183    const char * kernel_path);
184
185// check/rebuild CSFDE caches
186Boolean check_csfde(struct bootCaches *caches);
187int rebuild_csfde_cache(struct bootCaches *caches);
188int writeCSFDEProps(int scopefd, CFDictionaryRef ectx,
189                    char *cspvbsd, char *dstpath);
190Boolean check_loccache(struct bootCaches *caches);
191int rebuild_loccache(struct bootCaches *caches);
192
193// diskarb helpers
194void _daDone(DADiskRef disk, DADissenterRef dissenter, void *ctx);
195int updateMount(mountpoint_t mount, uint32_t mntgoal);
196
197
198pid_t launch_rebuild_all(char * rootPath, Boolean force, Boolean wait);
199
200#endif /* __BOOTCACHES_H__ */
201
202