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); 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); 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 static OSReturn readMkext1Archive( 329 OSData * mkextData, 330 uint32_t * checksumPtr); 331 bool initWithMkext1Info( 332 OSDictionary * anInfoDict, 333 OSData * executableWrapper, 334 OSData * mkextData); 335 static OSData * extractMkext1Entry( 336 const void * mkextFileBase, 337 const void * entry); 338 339 /* Dependencies. 340 */ 341 virtual bool resolveDependencies( 342 OSArray * loopStack = NULL); // priv/prot 343 virtual bool addBleedthroughDependencies(OSArray * anArray); 344 virtual bool flushDependencies(bool forceFlag = false); // priv/prot 345 virtual uint32_t getNumDependencies(void); 346 virtual OSArray * getDependencies(void); 347 348 /* User-space requests (load/generic). 349 */ 350 static OSReturn loadFromMkext( 351 OSKextLogSpec clientLogSpec, 352 char * mkextBuffer, 353 uint32_t mkextBufferLength, 354 char ** logInfoOut, 355 uint32_t * logInfoLengthOut); 356 static OSReturn handleRequest( 357 host_priv_t hostPriv, 358 OSKextLogSpec clientLogSpec, 359 char * requestBuffer, 360 uint32_t requestLength, 361 char ** responseOut, 362 uint32_t * responseLengthOut, 363 char ** logInfoOut, 364 uint32_t * logInfoLengthOut); 365 static OSReturn serializeLogInfo( 366 OSArray * logInfoArray, 367 char ** logInfoOut, 368 uint32_t * logInfoLengthOut); 369 370 /* Loading. 371 */ 372 virtual OSReturn load( 373 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 374 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 375 OSArray * personalityNames = NULL); // priv/prot 376 virtual OSReturn unload(void); 377 virtual OSReturn queueKextNotification( 378 const char * notificationName, 379 OSString * kextIdentifier); 380 381 static void recordIdentifierRequest( 382 OSString * kextIdentifier); 383 384 virtual OSReturn slidePrelinkedExecutable(void); 385 virtual OSReturn loadExecutable(void); 386 virtual void jettisonLinkeditSegment(void); 387 static void considerDestroyingLinkContext(void); 388 virtual OSData * getExecutable(void); 389 virtual void setLinkedExecutable(OSData * anExecutable); 390 391#if CONFIG_DTRACE 392 friend void OSKextRegisterKextsWithDTrace(void); 393 static void registerKextsWithDTrace(void); 394 virtual void registerWithDTrace(void); 395 virtual void unregisterWithDTrace(void); 396#endif /* CONFIG_DTRACE */ 397 398 virtual OSReturn start(bool startDependenciesFlag = true); 399 virtual OSReturn stop(void); 400 virtual OSReturn setVMProtections(void); 401 virtual boolean_t segmentShouldBeWired(kernel_segment_command_t *seg); 402 virtual OSReturn validateKextMapping(bool startFlag); 403 virtual boolean_t verifySegmentMapping(kernel_segment_command_t *seg); 404 405 static OSArray * copyAllKextPersonalities( 406 bool filterSafeBootFlag = false); 407 408 static void setPrelinkedPersonalities(OSArray * personalitiesArray); 409 410 static void sendAllKextPersonalitiesToCatalog( 411 bool startMatching = false); 412 virtual OSReturn sendPersonalitiesToCatalog( 413 bool startMatching = false, 414 OSArray * personalityNames = NULL); 415 416 static bool canUnloadKextWithIdentifier( 417 OSString * kextIdentifier, 418 bool checkClassesFlag = true); 419 420 static OSReturn autounloadKext(OSKext * aKext); 421 422 /* Sync with user space. 423 */ 424 static OSReturn pingKextd(void); 425 426 /* Getting info about loaded kexts (kextstat). 427 */ 428 static OSDictionary * copyLoadedKextInfo( 429 OSArray * kextIdentifiers = NULL, 430 OSArray * keys = NULL); 431 virtual OSDictionary * copyInfo(OSArray * keys = NULL); 432 433 /* Logging to user space. 434 */ 435 static OSKextLogSpec setUserSpaceLogFilter( 436 OSKextLogSpec userLogSpec, 437 bool captureFlag = false); 438 static OSArray * clearUserSpaceLogFilter(void); 439 static OSKextLogSpec getUserSpaceLogFilter(void); 440 441 /* OSMetaClasses defined by kext. 442 */ 443 virtual OSReturn addClass( 444 OSMetaClass * aClass, 445 uint32_t numClasses); 446 virtual OSReturn removeClass( 447 OSMetaClass * aClass); 448 virtual bool hasOSMetaClassInstances(void); 449 virtual OSSet * getMetaClasses(void); 450 static void reportOSMetaClassInstances( 451 const char * kextIdentifier, 452 OSKextLogSpec msgLogSpec); 453 virtual void reportOSMetaClassInstances( 454 OSKextLogSpec msgLogSpec); 455 456 /* Resource requests and other callback stuff. 457 */ 458 static OSReturn dispatchResource(OSDictionary * requestDict); 459 460 static OSReturn dequeueCallbackForRequestTag( 461 OSKextRequestTag requestTag, 462 OSDictionary ** callbackRecordOut); 463 static OSReturn dequeueCallbackForRequestTag( 464 OSNumber * requestTagNum, 465 OSDictionary ** callbackRecordOut); 466 static void invokeRequestCallback( 467 OSDictionary * callbackRecord, 468 OSReturn requestResult); 469 virtual void invokeOrCancelRequestCallbacks( 470 OSReturn callbackResult, 471 bool invokeFlag = true); 472 virtual uint32_t countRequestCallbacks(void); 473 474 /* panic() support. 475 */ 476 static void printKextsInBacktrace( 477 vm_offset_t * addr, 478 unsigned int cnt, 479 int (* printf_func)(const char *fmt, ...), 480 bool lockFlag); 481 static boolean_t summaryIsInBacktrace( 482 OSKextLoadedKextSummary * summary, 483 vm_offset_t * addr, 484 unsigned int cnt); 485 static void printSummary( 486 OSKextLoadedKextSummary * summary, 487 int (* printf_func)(const char *fmt, ...)); 488 489 static uint32_t saveLoadedKextPanicListTyped( 490 const char * prefix, 491 int invertFlag, 492 int libsFlag, 493 char * paniclist, 494 uint32_t list_size, 495 uint32_t * list_length_ptr); 496 static void saveLoadedKextPanicList(void); 497 void savePanicString(bool isLoading); 498 static void printKextPanicLists(int (*printf_func)(const char *fmt, ...)); 499 500 /* Kext summary support. 501 */ 502 static void updateLoadedKextSummaries(void); 503 void updateLoadedKextSummary(OSKextLoadedKextSummary *summary); 504 505 /* C++ Initialization. 506 */ 507 virtual void setCPPInitialized(bool initialized=true); 508 509 510 511#if PRAGMA_MARK 512/**************************************/ 513#pragma mark Public Functions 514/**************************************/ 515#endif 516public: 517 // caller must release 518 static OSKext * lookupKextWithIdentifier(const char * kextIdentifier); 519 static OSKext * lookupKextWithIdentifier(OSString * kextIdentifier); 520 static OSKext * lookupKextWithLoadTag(OSKextLoadTag aTag); 521 static OSKext * lookupKextWithAddress(vm_address_t address); 522 523 static bool isKextWithIdentifierLoaded(const char * kextIdentifier); 524 525 static OSReturn loadKextWithIdentifier( 526 const char * kextIdentifier, 527 Boolean allowDeferFlag = true, 528 Boolean delayAutounloadFlag = false, 529 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 530 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 531 OSArray * personalityNames = NULL); 532 static OSReturn loadKextWithIdentifier( 533 OSString * kextIdentifier, 534 Boolean allowDeferFlag = true, 535 Boolean delayAutounloadFlag = false, 536 OSKextExcludeLevel startOpt = kOSKextExcludeNone, 537 OSKextExcludeLevel startMatchingOpt = kOSKextExcludeAll, 538 OSArray * personalityNames = NULL); 539 static OSReturn removeKextWithIdentifier( 540 const char * kextIdentifier, 541 bool terminateServicesAndRemovePersonalitiesFlag = false); 542 static OSReturn removeKextWithLoadTag( 543 OSKextLoadTag loadTag, 544 bool terminateServicesAndRemovePersonalitiesFlag = false); 545 546 static OSReturn requestResource( 547 const char * kextIdentifier, 548 const char * resourceName, 549 OSKextRequestResourceCallback callback, 550 void * context, 551 OSKextRequestTag * requestTagOut); 552 static OSReturn cancelRequest( 553 OSKextRequestTag requestTag, 554 void ** contextOut); 555 556 static void considerUnloads(Boolean rescheduleOnlyFlag = false); 557 static void flushNonloadedKexts(Boolean flushPrelinkedKexts); 558 static void setKextdActive(Boolean active = true); 559 static void setDeferredLoadSucceeded(Boolean succeeded = true); 560 static void considerRebuildOfPrelinkedKernel(void); 561 static void createExcludeListFromBooterData( 562 OSDictionary * theDictionary, 563 OSCollectionIterator * theIterator); 564 static void createExcludeListFromPrelinkInfo(OSArray * theInfoArray); 565 566 virtual bool setAutounloadEnabled(bool flag); 567 568 virtual const OSSymbol * getIdentifier(void); 569 virtual const char * getIdentifierCString(void); 570 virtual OSKextVersion getVersion(void); 571 virtual OSKextVersion getCompatibleVersion(void); 572 virtual bool isLibrary(void); 573 virtual bool isCompatibleWithVersion(OSKextVersion aVersion); 574 virtual OSObject * getPropertyForHostArch(const char * key); 575 576 virtual OSKextLoadTag getLoadTag(void); 577 virtual void getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize); 578 virtual OSData * copyUUID(void); 579 virtual OSArray * copyPersonalitiesArray(void); 580 581 /* This removes personalities naming the kext (by CFBundleIdentifier), 582 * not all personalities defined by the kext (IOPersonalityPublisher or CFBundleIdentifier). 583 */ 584 virtual void removePersonalitiesFromCatalog(void); 585 586 /* Converts common string-valued properties to OSSymbols for lower memory consumption. 587 */ 588 static void uniquePersonalityProperties(OSDictionary * personalityDict); 589 590 virtual bool declaresExecutable(void); // might be missing 591 virtual bool isInterface(void); 592 virtual bool isKernel(void); 593 virtual bool isKernelComponent(void); 594 virtual bool isExecutable(void); 595 virtual bool isLoadableInSafeBoot(void); 596 virtual bool isPrelinked(void); 597 virtual bool isLoaded(void); 598 virtual bool isStarted(void); 599 virtual bool isCPPInitialized(void); 600}; 601 602 603#endif /* !_LIBKERN_OSKEXT_H */ 604