1/* 2 * Copyright (c) 2008-2012 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#ifndef _LIBKERN_OSKEXT_H 30#define _LIBKERN_OSKEXT_H 31 32extern "C" { 33#include <kern/thread_call.h> 34#include <libkern/OSKextLibPrivate.h> 35#include <libkern/kernel_mach_header.h> 36#include <libkern/kxld.h> 37#include <mach/kmod.h> 38 39#ifdef XNU_KERNEL_PRIVATE 40#include <kern/thread_call.h> 41#endif /* XNU_KERNEL_PRIVATE */ 42} 43 44#include <libkern/OSKextLib.h> 45#include <libkern/OSKextLibPrivate.h> 46#include <libkern/c++/OSObject.h> 47#include <libkern/c++/OSContainers.h> 48#include <IOKit/IOLocks.h> 49 50/********************************************************************* 51* C functions used for callbacks. 52*********************************************************************/ 53#ifdef XNU_KERNEL_PRIVATE 54extern "C" { 55void osdata_kmem_free(void * ptr, unsigned int length); 56void osdata_phys_free(void * ptr, unsigned int length); 57void osdata_vm_deallocate(void * ptr, unsigned int length); 58}; 59#endif /* XNU_KERNEL_PRIVATE */ 60 61/********************************************************************* 62* C Function Prototypes for Friend Declarations. 63*********************************************************************/ 64class OSKext; 65 66extern "C" { 67 68void OSKextLog( 69 OSKext * aKext, 70 OSKextLogSpec msgLogSpec, 71 const char * format, ...) 72 __attribute__((format(printf, 3, 4))); 73 74void OSKextVLog( 75 OSKext * aKext, 76 OSKextLogSpec msgLogSpec, 77 const char * format, 78 va_list srcArgList); 79 80#ifdef XNU_KERNEL_PRIVATE 81void OSKextRemoveKextBootstrap(void); 82void IOSystemShutdownNotification(void); 83 84kern_return_t OSRuntimeInitializeCPP( 85 kmod_info_t * kmodInfo, 86 void * data); 87kern_return_t OSRuntimeFinalizeCPP( 88 kmod_info_t * kmodInfo, 89 void * data); 90 91kern_return_t is_io_catalog_send_data( 92 mach_port_t masterPort, 93 uint32_t flag, 94 io_buf_ptr_t inData, 95 mach_msg_type_number_t inDataCount, 96 kern_return_t * result); 97 98void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t); 99 100 101#endif /* XNU_KERNEL_PRIVATE */ 102}; 103 104/********************************************************************/ 105#if PRAGMA_MARK 106#pragma mark - 107#endif 108/* 109 * @class OSKext 110 */ 111/********************************************************************/ 112class OSKext : public OSObject 113{ 114 OSDeclareDefaultStructors(OSKext) 115 116#if PRAGMA_MARK 117/**************************************/ 118#pragma mark Friend Declarations 119/**************************************/ 120#endif 121 friend class IOCatalogue; 122 friend class KLDBootstrap; 123 friend class OSMetaClass; 124 125#ifdef XNU_KERNEL_PRIVATE 126 friend void OSKextVLog( 127 OSKext * aKext, 128 OSKextLogSpec msgLogSpec, 129 const char * format, 130 va_list srcArgList); 131 132 friend void OSKextRemoveKextBootstrap(void); 133 friend void IOSystemShutdownNotification(void); 134 friend OSReturn OSKextUnloadKextWithLoadTag(uint32_t); 135 136 friend kern_return_t kext_request( 137 host_priv_t hostPriv, 138 /* in only */ uint32_t clientLogSpec, 139 /* in only */ vm_offset_t requestIn, 140 /* in only */ mach_msg_type_number_t requestLengthIn, 141 /* out only */ vm_offset_t * responseOut, 142 /* out only */ mach_msg_type_number_t * responseLengthOut, 143 /* out only */ vm_offset_t * logDataOut, 144 /* out only */ mach_msg_type_number_t * logDataLengthOut, 145 /* out only */ kern_return_t * op_result); 146 147 friend kxld_addr_t kern_allocate( 148 u_long size, 149 KXLDAllocateFlags * flags, 150 void * user_data); 151 152 friend void kxld_log_shim( 153 KXLDLogSubsystem subsystem, 154 KXLDLogLevel level, 155 const char * format, 156 va_list argList, 157 void * user_data); 158 159 friend void _OSKextConsiderUnloads( 160 __unused thread_call_param_t p0, 161 __unused thread_call_param_t p1); 162 163 friend kern_return_t OSRuntimeInitializeCPP( 164 kmod_info_t * kmodInfo, 165 void * data); 166 friend kern_return_t OSRuntimeFinalizeCPP( 167 kmod_info_t * kmodInfo, 168 void * data); 169 170 friend kern_return_t is_io_catalog_send_data( 171 mach_port_t masterPort, 172 uint32_t flag, 173 io_buf_ptr_t inData, 174 mach_msg_type_number_t inDataCount, 175 kern_return_t * result); 176 177 friend void kmod_panic_dump(vm_offset_t*, unsigned int); 178 friend void kmod_dump_log(vm_offset_t*, unsigned int, boolean_t); 179 friend void kext_dump_panic_lists(int (*printf_func)(const char * fmt, ...)); 180 181 182#endif /* XNU_KERNEL_PRIVATE */ 183 184private: 185 186 /************************* 187 * Instance variables 188 *************************/ 189 OSDictionary * infoDict; 190 191 const OSSymbol * bundleID; 192 OSString * path; // not necessarily correct :-/ 193 OSString * executableRelPath; // relative to bundle 194 195 OSKextVersion version; // parsed 196 OSKextVersion compatibleVersion; // parsed 197 198 /* These fields are required for tracking loaded kexts and 199 * will always have values for a loaded kext. 200 */ 201 OSKextLoadTag loadTag; // 'id' from old kmod_info; 202 // kOSKextInvalidLoadTag invalid 203 kmod_info_t * kmod_info; // address into linkedExec./alloced for interface 204 205 OSArray * dependencies; // kernel resource does not have any; 206 // links directly to kernel 207 208 /* Only real kexts have these; interface kexts do not. 209 */ 210 OSData * linkedExecutable; 211 OSSet * metaClasses; // for C++/OSMetaClass kexts 212 213 /* Only interface kexts have these; non-interface kexts can get at them 214 * in the linked Executable. 215 */ 216 OSData * interfaceUUID; 217 218 struct { 219 unsigned int loggingEnabled:1; 220 221 unsigned int hasAllDependencies:1; 222 unsigned int hasBleedthrough:1; 223 224 unsigned int interface:1; 225 unsigned int kernelComponent:1; 226 unsigned int prelinked:1; 227 unsigned int loaded:1; 228 unsigned int dtraceInitialized:1; 229 unsigned int starting:1; 230 unsigned int started:1; 231 unsigned int stopping:1; 232 unsigned int unloading:1; 233 234 unsigned int autounloadEnabled:1; 235 unsigned int delayAutounload:1; // for development 236 237 unsigned int CPPInitialized:1; 238 unsigned int jettisonLinkeditSeg:1; 239 } flags; 240 241#if PRAGMA_MARK 242/**************************************/ 243#pragma mark Private Functions 244/**************************************/ 245#endif 246 247#ifdef XNU_KERNEL_PRIVATE 248 /* Startup/shutdown phases. 249 */ 250public: 251 static void initialize(void); 252 static OSDictionary * copyKexts(void); 253 static OSReturn removeKextBootstrap(void); 254 static void willShutdown(void); // called by IOPMrootDomain on shutdown 255#endif /* XNU_KERNEL_PRIVATE */ 256 257private: 258 /* Called by power management at sleep/shutdown. 259 */ 260 static bool setLoadEnabled(bool flag); 261 static bool setUnloadEnabled(bool flag); 262 static bool setAutounloadsEnabled(bool flag); 263 static bool setKernelRequestsEnabled(bool flag); 264 265 // all getters subject to race condition, caller beware 266 static bool getLoadEnabled(void); 267 static bool getUnloadEnabled(void); 268 static bool getAutounloadEnabled(void); 269 static bool getKernelRequestsEnabled(void); 270 271 /* Instance life cycle. 272 */ 273 static OSKext * withBooterData( 274 OSString * deviceTreeName, 275 OSData * booterData); 276 virtual bool initWithBooterData( 277 OSString * deviceTreeName, 278 OSData * booterData); 279 280 static OSKext * withPrelinkedInfoDict( 281 OSDictionary * infoDict); 282 virtual bool initWithPrelinkedInfoDict( 283 OSDictionary * infoDict); 284 285 static OSKext * withMkext2Info( 286 OSDictionary * anInfoDict, 287 OSData * mkextData); 288 virtual bool initWithMkext2Info( 289 OSDictionary * anInfoDict, 290 OSData * mkextData); 291 292 virtual bool setInfoDictionaryAndPath( 293 OSDictionary * aDictionary, 294 OSString * aPath); 295 virtual bool setExecutable( 296 OSData * anExecutable, 297 OSData * externalData = NULL, 298 bool externalDataIsMkext = false); 299 virtual bool registerIdentifier(void); 300 301 virtual void free(void); 302 303 static OSReturn removeKext( 304 OSKext * aKext, 305 bool terminateServicesAndRemovePersonalitiesFlag = false); 306 307 virtual bool isInExcludeList(void); 308 309 /* Mkexts. 310 */ 311 static OSReturn readMkextArchive( 312 OSData * mkextData, 313 uint32_t * checksumPtr = NULL); 314 static OSReturn readMkext2Archive( 315 OSData * mkextData, 316 OSDictionary ** mkextPlistOut, 317 uint32_t * checksumPtr = NULL); 318 virtual OSData * createMkext2FileEntry( 319 OSData * mkextData, 320 OSNumber * offsetNum, 321 const char * entryName); 322 virtual OSData * extractMkext2FileData( 323 UInt8 * data, 324 const char * name, 325 uint32_t compressedSize, 326 uint32_t fullSize); 327 328 /* Dependencies. 329 */ 330 virtual bool resolveDependencies( 331 OSArray * loopStack = NULL); // priv/prot 332 virtual bool addBleedthroughDependencies(OSArray * anArray); 333 virtual bool flushDependencies(bool forceFlag = false); // priv/prot 334 virtual uint32_t getNumDependencies(void); 335 virtual OSArray * getDependencies(void); 336 337 /* User-space requests (load/generic). 338 */ 339 static OSReturn loadFromMkext( 340 OSKextLogSpec clientLogSpec, 341 char * mkextBuffer, 342 uint32_t mkextBufferLength, 343 char ** logInfoOut, 344 uint32_t * logInfoLengthOut); 345 static OSReturn handleRequest( 346 host_priv_t hostPriv, 347 OSKextLogSpec clientLogSpec, 348 char * requestBuffer, 349 uint32_t requestLength, 350 char ** responseOut, 351 uint32_t * responseLengthOut, 352 char ** logInfoOut, 353 uint32_t * logInfoLengthOut); 354 static OSReturn serializeLogInfo( 355 OSArray * logInfoArray, 356 char ** logInfoOut, 357 uint32_t * logInfoLengthOut); 358 359 /* Loading. 360 */ 361 virtual OSReturn load( 362 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 363 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 364 OSArray * personalityNames = NULL); // priv/prot 365 virtual OSReturn unload(void); 366 virtual OSReturn queueKextNotification( 367 const char * notificationName, 368 OSString * kextIdentifier); 369 370 static void recordIdentifierRequest( 371 OSString * kextIdentifier); 372 373 virtual OSReturn slidePrelinkedExecutable(void); 374 virtual OSReturn loadExecutable(void); 375 virtual void jettisonLinkeditSegment(void); 376 static void considerDestroyingLinkContext(void); 377 virtual OSData * getExecutable(void); 378 virtual void setLinkedExecutable(OSData * anExecutable); 379 380#if CONFIG_DTRACE 381 friend void OSKextRegisterKextsWithDTrace(void); 382 static void registerKextsWithDTrace(void); 383 virtual void registerWithDTrace(void); 384 virtual void unregisterWithDTrace(void); 385#endif /* CONFIG_DTRACE */ 386 387 virtual OSReturn start(bool startDependenciesFlag = true); 388 virtual OSReturn stop(void); 389 virtual OSReturn setVMProtections(void); 390 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg); 391 virtual OSReturn validateKextMapping(bool startFlag); 392 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg); 393 394 static OSArray * copyAllKextPersonalities( 395 bool filterSafeBootFlag = false); 396 397 static void setPrelinkedPersonalities(OSArray * personalitiesArray); 398 399 static void sendAllKextPersonalitiesToCatalog( 400 bool startMatching = false); 401 virtual OSReturn sendPersonalitiesToCatalog( 402 bool startMatching = false, 403 OSArray * personalityNames = NULL); 404 405 static bool canUnloadKextWithIdentifier( 406 OSString * kextIdentifier, 407 bool checkClassesFlag = true); 408 409 static OSReturn autounloadKext(OSKext * aKext); 410 411 /* Sync with user space. 412 */ 413 static OSReturn pingKextd(void); 414 415 /* Getting info about loaded kexts (kextstat). 416 */ 417 static OSDictionary * copyLoadedKextInfo( 418 OSArray * kextIdentifiers = NULL, 419 OSArray * keys = NULL); 420 virtual OSDictionary * copyInfo(OSArray * keys = NULL); 421 422 /* Logging to user space. 423 */ 424 static OSKextLogSpec setUserSpaceLogFilter( 425 OSKextLogSpec userLogSpec, 426 bool captureFlag = false); 427 static OSArray * clearUserSpaceLogFilter(void); 428 static OSKextLogSpec getUserSpaceLogFilter(void); 429 430 /* OSMetaClasses defined by kext. 431 */ 432 virtual OSReturn addClass( 433 OSMetaClass * aClass, 434 uint32_t numClasses); 435 virtual OSReturn removeClass( 436 OSMetaClass * aClass); 437 virtual bool hasOSMetaClassInstances(void); 438 virtual OSSet * getMetaClasses(void); 439 static void reportOSMetaClassInstances( 440 const char * kextIdentifier, 441 OSKextLogSpec msgLogSpec); 442 virtual void reportOSMetaClassInstances( 443 OSKextLogSpec msgLogSpec); 444 445 /* Resource requests and other callback stuff. 446 */ 447 static OSReturn dispatchResource(OSDictionary * requestDict); 448 449 static OSReturn dequeueCallbackForRequestTag( 450 OSKextRequestTag requestTag, 451 OSDictionary ** callbackRecordOut); 452 static OSReturn dequeueCallbackForRequestTag( 453 OSNumber * requestTagNum, 454 OSDictionary ** callbackRecordOut); 455 static void invokeRequestCallback( 456 OSDictionary * callbackRecord, 457 OSReturn requestResult); 458 virtual void invokeOrCancelRequestCallbacks( 459 OSReturn callbackResult, 460 bool invokeFlag = true); 461 virtual uint32_t countRequestCallbacks(void); 462 463 /* panic() support. 464 */ 465 static void printKextsInBacktrace( 466 vm_offset_t * addr, 467 unsigned int cnt, 468 int (* printf_func)(const char *fmt, ...), 469 bool lockFlag, 470 bool doUnslide); 471 static boolean_t summaryIsInBacktrace( 472 OSKextLoadedKextSummary * summary, 473 vm_offset_t * addr, 474 unsigned int cnt); 475 static void printSummary( 476 OSKextLoadedKextSummary * summary, 477 int (* printf_func)(const char *fmt, ...), 478 bool doUnslide); 479 480 static int saveLoadedKextPanicListTyped( 481 const char * prefix, 482 int invertFlag, 483 int libsFlag, 484 char * paniclist, 485 uint32_t list_size); 486 static void saveLoadedKextPanicList(void); 487 void savePanicString(bool isLoading); 488 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...)); 489 490 /* Kext summary support. 491 */ 492 static void updateLoadedKextSummaries(void); 493 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary); 494 495 /* C++ Initialization. 496 */ 497 virtual void setCPPInitialized(bool initialized=true); 498 499 500 501#if PRAGMA_MARK 502/**************************************/ 503#pragma mark Public Functions 504/**************************************/ 505#endif 506public: 507 // caller must release 508 static OSKext * lookupKextWithIdentifier(const char * kextIdentifier); 509 static OSKext * lookupKextWithIdentifier(OSString * kextIdentifier); 510 static OSKext * lookupKextWithLoadTag(OSKextLoadTag aTag); 511 static OSKext * lookupKextWithAddress(vm_address_t address); 512 513 static bool isKextWithIdentifierLoaded(const char * kextIdentifier); 514 515 static OSReturn loadKextWithIdentifier( 516 const char * kextIdentifier, 517 Boolean allowDeferFlag = true, 518 Boolean delayAutounloadFlag = false, 519 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 520 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 521 OSArray * personalityNames = NULL); 522 static OSReturn loadKextWithIdentifier( 523 OSString * kextIdentifier, 524 Boolean allowDeferFlag = true, 525 Boolean delayAutounloadFlag = false, 526 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 527 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 528 OSArray * personalityNames = NULL); 529 static OSReturn removeKextWithIdentifier( 530 const char * kextIdentifier, 531 bool terminateServicesAndRemovePersonalitiesFlag = false); 532 static OSReturn removeKextWithLoadTag( 533 OSKextLoadTag loadTag, 534 bool terminateServicesAndRemovePersonalitiesFlag = false); 535 536 static OSReturn requestResource( 537 const char * kextIdentifier, 538 const char * resourceName, 539 OSKextRequestResourceCallback callback, 540 void * context, 541 OSKextRequestTag * requestTagOut); 542 static OSReturn cancelRequest( 543 OSKextRequestTag requestTag, 544 void ** contextOut); 545 546 static void considerUnloads(Boolean rescheduleOnlyFlag = false); 547 static void flushNonloadedKexts(Boolean flushPrelinkedKexts); 548 static void setKextdActive(Boolean active = true); 549 static void setDeferredLoadSucceeded(Boolean succeeded = true); 550 static void considerRebuildOfPrelinkedKernel(void); 551 static void createExcludeListFromBooterData( 552 OSDictionary * theDictionary, 553 OSCollectionIterator * theIterator); 554 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray); 555 556 virtual bool setAutounloadEnabled(bool flag); 557 558 virtual const OSSymbol * getIdentifier(void); 559 virtual const char * getIdentifierCString(void); 560 virtual OSKextVersion getVersion(void); 561 virtual OSKextVersion getCompatibleVersion(void); 562 virtual bool isLibrary(void); 563 virtual bool isCompatibleWithVersion(OSKextVersion aVersion); 564 virtual OSObject * getPropertyForHostArch(const char * key); 565 566 virtual OSKextLoadTag getLoadTag(void); 567 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize); 568 virtual OSData * copyUUID(void); 569 virtual OSArray * copyPersonalitiesArray(void); 570 571 /* This removes personalities naming the kext (by CFBundleIdentifier), 572 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier). 573 */ 574 virtual void removePersonalitiesFromCatalog(void); 575 576 /* Converts common string-valued properties to OSSymbols for lower memory consumption. 577 */ 578 static void uniquePersonalityProperties(OSDictionary * personalityDict); 579 580 virtual bool declaresExecutable(void); // might be missing 581 virtual bool isInterface(void); 582 virtual bool isKernel(void); 583 virtual bool isKernelComponent(void); 584 virtual bool isExecutable(void); 585 virtual bool isLoadableInSafeBoot(void); 586 virtual bool isPrelinked(void); 587 virtual bool isLoaded(void); 588 virtual bool isStarted(void); 589 virtual bool isCPPInitialized(void); 590}; 591 592 593#endif /* !_LIBKERN_OSKEXT_H */ 594