2 * Copyright (c) 1998-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1998 Apple Inc. All rights reserved.
35 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
36 * support for mandatory and extensible security protections. This notice
37 * is included in support of clause 2.2 (b) of the Apple Public License,
42 #include <machine/machine_routines.h>
43 #include <libkern/kernel_mach_header.h>
44 #include <kern/host.h>
45 #include <security/mac_data.h>
48 #include <libkern/c++/OSContainers.h>
49 #include <libkern/c++/OSUnserialize.h>
50 #include <libkern/c++/OSKext.h>
51 #include <libkern/OSKextLibPrivate.h>
52 #include <libkern/OSDebug.h>
54 #include <IOKit/IODeviceTreeSupport.h>
55 #include <IOKit/IOService.h>
56 #include <IOKit/IOCatalogue.h>
58 #include <IOKit/IOLib.h>
59 #include <IOKit/assert.h>
62 #pragma mark Internal Declarations
64 /*********************************************************************
65 *********************************************************************/
67 IOCatalogue
* gIOCatalogue
;
68 const OSSymbol
* gIOClassKey
;
69 const OSSymbol
* gIOProbeScoreKey
;
70 const OSSymbol
* gIOModuleIdentifierKey
;
71 IORWLock
* gIOCatalogLock
;
74 #pragma mark Utility functions
78 #pragma mark IOCatalogue class implementation
80 /*********************************************************************
81 *********************************************************************/
83 #define super OSObject
84 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
86 /*********************************************************************
87 *********************************************************************/
88 void IOCatalogue::initialize(void)
91 OSString
* errorString
;
94 extern const char * gIOKernelConfigTables
;
96 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
97 if (!array
&& errorString
) {
98 IOLog("KernelConfigTables syntax error: %s\n",
99 errorString
->getCStringNoCopy());
100 errorString
->release();
103 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
104 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
105 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kCFBundleIdentifierKey
);
107 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
108 && gIOModuleIdentifierKey
);
110 gIOCatalogue
= new IOCatalogue
;
111 assert(gIOCatalogue
);
112 rc
= gIOCatalogue
->init(array
);
117 /*********************************************************************
118 * Initialize the IOCatalog object.
119 *********************************************************************/
120 OSArray
* IOCatalogue::arrayForPersonality(OSDictionary
* dict
)
122 const OSSymbol
* sym
;
124 sym
= OSDynamicCast(OSSymbol
, dict
->getObject(gIOProviderClassKey
));
125 if (!sym
) return (0);
127 return ((OSArray
*) personalities
->getObject(sym
));
130 void IOCatalogue::addPersonality(OSDictionary
* dict
)
132 const OSSymbol
* sym
;
135 sym
= OSDynamicCast(OSSymbol
, dict
->getObject(gIOProviderClassKey
));
137 arr
= (OSArray
*) personalities
->getObject(sym
);
138 if (arr
) arr
->setObject(dict
);
141 arr
= OSArray::withObjects((const OSObject
**)&dict
, 1, 2);
142 personalities
->setObject(sym
, arr
);
147 /*********************************************************************
148 * Initialize the IOCatalog object.
149 *********************************************************************/
150 bool IOCatalogue::init(OSArray
* initArray
)
155 if ( !super::init() )
160 personalities
= OSDictionary::withCapacity(32);
161 personalities
->setOptions(OSCollection::kSort
, OSCollection::kSort
);
162 for (unsigned int idx
= 0; (obj
= initArray
->getObject(idx
)); idx
++)
164 dict
= OSDynamicCast(OSDictionary
, obj
);
166 OSKext::uniquePersonalityProperties(dict
);
167 if( 0 == dict
->getObject( gIOClassKey
))
169 IOLog("Missing or bad \"%s\" key\n",
170 gIOClassKey
->getCStringNoCopy());
173 dict
->setObject("KernelConfigTable", kOSBooleanTrue
);
174 addPersonality(dict
);
177 gIOCatalogLock
= IORWLockAlloc();
178 lock
= gIOCatalogLock
;
183 /*********************************************************************
184 * Release all resources used by IOCatalogue and deallocate.
185 * This will probably never be called.
186 *********************************************************************/
187 void IOCatalogue::free( void )
192 /*********************************************************************
193 *********************************************************************/
195 IOCatalogue::findDrivers(
197 SInt32
* generationCount
)
199 OSDictionary
* nextTable
;
202 const OSMetaClass
* meta
;
205 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
206 (void *)gIOProbeScoreKey
);
212 meta
= service
->getMetaClass();
215 array
= (OSArray
*) personalities
->getObject(meta
->getClassNameSymbol());
216 if (array
) for (idx
= 0; (nextTable
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
218 set
->setObject(nextTable
);
220 if (meta
== &IOService::gMetaClass
) break;
221 meta
= meta
->getSuperClass();
224 *generationCount
= getGenerationCount();
226 IORWLockUnlock(lock
);
231 /*********************************************************************
232 * Is personality already in the catalog?
233 *********************************************************************/
235 IOCatalogue::findDrivers(
236 OSDictionary
* matching
,
237 SInt32
* generationCount
)
239 OSCollectionIterator
* iter
;
243 const OSSymbol
* key
;
246 OSKext::uniquePersonalityProperties(matching
);
248 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
249 (void *)gIOProbeScoreKey
);
250 if (!set
) return (0);
251 iter
= OSCollectionIterator::withCollection(personalities
);
259 while ((key
= (const OSSymbol
*) iter
->getNextObject()))
261 array
= (OSArray
*) personalities
->getObject(key
);
262 if (array
) for (idx
= 0; (dict
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
264 /* This comparison must be done with only the keys in the
265 * "matching" dict to enable general searches.
267 if ( dict
->isEqualTo(matching
, matching
) )
268 set
->setObject(dict
);
271 *generationCount
= getGenerationCount();
272 IORWLockUnlock(lock
);
278 /*********************************************************************
279 * Add driver config tables to catalog and start matching process.
281 * Important that existing personalities are kept (not replaced)
282 * if duplicates found. Personalities can come from OSKext objects
283 * or from userland kext library. We want to minimize distinct
284 * copies between OSKext & IOCatalogue.
286 * xxx - userlib used to refuse to send personalities with IOKitDebug
287 * xxx - during safe boot. That would be better implemented here.
288 *********************************************************************/
290 bool IOCatalogue::addDrivers(
295 OSCollectionIterator
* iter
= NULL
; // must release
296 OSOrderedSet
* set
= NULL
; // must release
297 OSObject
* object
= NULL
; // do not release
298 OSArray
* persons
= NULL
; // do not release
300 persons
= OSDynamicCast(OSArray
, drivers
);
305 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
306 (void *)gIOProbeScoreKey
);
311 iter
= OSCollectionIterator::withCollection(persons
);
316 /* Start with success; clear it on an error.
321 while ( (object
= iter
->getNextObject()) ) {
323 // xxx Deleted OSBundleModuleDemand check; will handle in other ways for SL
325 OSDictionary
* personality
= OSDynamicCast(OSDictionary
, object
);
330 IOLog("IOCatalogue::addDrivers() encountered non-dictionary; bailing.\n");
335 OSKext::uniquePersonalityProperties(personality
);
337 // Add driver personality to catalogue.
339 OSArray
* array
= arrayForPersonality(personality
);
340 if (!array
) addPersonality(personality
);
343 count
= array
->getCount();
345 OSDictionary
* driver
;
347 // Be sure not to double up on personalities.
348 driver
= (OSDictionary
*)array
->getObject(count
);
350 /* Unlike in other functions, this comparison must be exact!
351 * The catalogue must be able to contain personalities that
352 * are proper supersets of others.
353 * Do not compare just the properties present in one driver
354 * personality or the other.
356 if (personality
->isEqualTo(driver
)) {
364 result
= array
->setObject(personality
);
370 set
->setObject(personality
);
372 // Start device matching.
373 if (result
&& doNubMatching
&& (set
->getCount() > 0)) {
374 IOService::catalogNewDrivers(set
);
377 IORWLockUnlock(lock
);
380 if (set
) set
->release();
381 if (iter
) iter
->release();
386 /*********************************************************************
387 * Remove drivers from the catalog which match the
388 * properties in the matching dictionary.
389 *********************************************************************/
391 IOCatalogue::removeDrivers(
392 OSDictionary
* matching
,
396 OSCollectionIterator
* iter
;
399 const OSSymbol
* key
;
405 set
= OSOrderedSet::withCapacity(10,
407 (void *)gIOProbeScoreKey
);
410 iter
= OSCollectionIterator::withCollection(personalities
);
418 while ((key
= (const OSSymbol
*) iter
->getNextObject()))
420 array
= (OSArray
*) personalities
->getObject(key
);
421 if (array
) for (idx
= 0; (dict
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
423 /* This comparison must be done with only the keys in the
424 * "matching" dict to enable general searches.
426 if ( dict
->isEqualTo(matching
, matching
) ) {
427 set
->setObject(dict
);
428 array
->removeObject(idx
);
432 // Start device matching.
433 if ( doNubMatching
&& (set
->getCount() > 0) ) {
434 IOService::catalogNewDrivers(set
);
438 IORWLockUnlock(lock
);
446 // Return the generation count.
447 SInt32
IOCatalogue::getGenerationCount(void) const
449 return( generation
);
452 bool IOCatalogue::isModuleLoaded(OSString
* moduleName
) const
454 return isModuleLoaded(moduleName
->getCStringNoCopy());
457 bool IOCatalogue::isModuleLoaded(const char * moduleName
) const
460 ret
= OSKext::loadKextWithIdentifier(moduleName
);
461 if (kOSKextReturnDeferred
== ret
) {
462 // a request has been queued but the module isn't necessarily
463 // loaded yet, so stall.
466 // module is present or never will be
470 // Check to see if module has been loaded already.
471 bool IOCatalogue::isModuleLoaded(OSDictionary
* driver
) const
473 OSString
* moduleName
= NULL
;
474 OSString
* publisherName
= NULL
;
479 /* The personalities of codeless kexts often contain the bundle ID of the
480 * kext they reference, and not the bundle ID of the codeless kext itself.
481 * The prelinked kernel needs to know the bundle ID of the codeless kext
482 * so it can include these personalities, so OSKext stores that bundle ID
483 * in the IOPersonalityPublisher key, and we record it as requested here.
485 publisherName
= OSDynamicCast(OSString
,
486 driver
->getObject(kIOPersonalityPublisherKey
));
487 OSKext::recordIdentifierRequest(publisherName
);
489 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
491 return isModuleLoaded(moduleName
);
493 /* If a personality doesn't hold the "CFBundleIdentifier" key
494 * it is assumed to be an "in-kernel" driver.
499 /* This function is called after a module has been loaded.
500 * Is invoked from user client call, ultimately from IOKitLib's
501 * IOCatalogueModuleLoaded(). Sent from kextd.
503 void IOCatalogue::moduleHasLoaded(OSString
* moduleName
)
507 dict
= OSDictionary::withCapacity(2);
508 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
512 (void) OSKext::setDeferredLoadSucceeded();
513 (void) OSKext::considerRebuildOfPrelinkedKernel();
516 void IOCatalogue::moduleHasLoaded(const char * moduleName
)
520 name
= OSString::withCString(moduleName
);
521 moduleHasLoaded(name
);
525 // xxx - return is really OSReturn/kern_return_t
526 IOReturn
IOCatalogue::unloadModule(OSString
* moduleName
) const
528 return OSKext::removeKextWithIdentifier(moduleName
->getCStringNoCopy());
531 IOReturn
IOCatalogue::_terminateDrivers(OSDictionary
* matching
)
539 return kIOReturnBadArgument
;
541 ret
= kIOReturnSuccess
;
543 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
544 kIORegistryIterateRecursively
);
546 return kIOReturnNoMemory
;
548 OSKext::uniquePersonalityProperties( matching
);
550 // terminate instances.
553 while( (service
= (IOService
*)iter
->getNextObject()) ) {
554 dict
= service
->getPropertyTable();
558 /* Terminate only for personalities that match the matching dictionary.
559 * This comparison must be done with only the keys in the
560 * "matching" dict to enable general matching.
562 if ( !dict
->isEqualTo(matching
, matching
) )
565 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
566 ret
= kIOReturnUnsupported
;
570 } while( !service
&& !iter
->isValid());
576 IOReturn
IOCatalogue::_removeDrivers(OSDictionary
* matching
)
578 IOReturn ret
= kIOReturnSuccess
;
579 OSCollectionIterator
* iter
;
582 const OSSymbol
* key
;
585 // remove configs from catalog.
587 iter
= OSCollectionIterator::withCollection(personalities
);
588 if (!iter
) return (kIOReturnNoMemory
);
590 while ((key
= (const OSSymbol
*) iter
->getNextObject()))
592 array
= (OSArray
*) personalities
->getObject(key
);
593 if (array
) for (idx
= 0; (dict
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
596 /* Remove from the catalogue's array any personalities
597 * that match the matching dictionary.
598 * This comparison must be done with only the keys in the
599 * "matching" dict to enable general matching.
601 if (dict
->isEqualTo(matching
, matching
))
603 array
->removeObject(idx
);
613 IOReturn
IOCatalogue::terminateDrivers(OSDictionary
* matching
)
617 ret
= _terminateDrivers(matching
);
619 if (kIOReturnSuccess
== ret
)
620 ret
= _removeDrivers(matching
);
621 IORWLockUnlock(lock
);
626 IOReturn
IOCatalogue::terminateDriversForModule(
627 OSString
* moduleName
,
632 bool isLoaded
= false;
634 /* Check first if the kext currently has any linkage dependents;
635 * in such a case the unload would fail so let's not terminate any
636 * IOServices (since doing so typically results in a panic when there
637 * are loaded dependencies). Note that we aren't locking the kext here
638 * so it might lose or gain dependents by the time we call unloadModule();
639 * I think that's ok, our unload can fail if a kext comes in on top of
640 * this one even after we've torn down IOService objects. Conversely,
641 * if we fail the unload here and then lose a library, the autounload
642 * thread will get us in short order.
644 if (OSKext::isKextWithIdentifierLoaded(moduleName
->getCStringNoCopy())) {
648 if (!OSKext::canUnloadKextWithIdentifier(moduleName
,
649 /* checkClasses */ false)) {
650 ret
= kOSKextReturnInUse
;
654 dict
= OSDictionary::withCapacity(1);
656 ret
= kIOReturnNoMemory
;
660 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
662 ret
= _terminateDrivers(dict
);
664 /* No goto between IOLock calls!
667 if (kIOReturnSuccess
== ret
) {
668 ret
= _removeDrivers(dict
);
671 // Unload the module itself.
672 if (unload
&& isLoaded
&& ret
== kIOReturnSuccess
) {
673 ret
= unloadModule(moduleName
);
676 IORWLockUnlock(lock
);
684 IOReturn
IOCatalogue::terminateDriversForModule(
685 const char * moduleName
,
691 name
= OSString::withCString(moduleName
);
693 return kIOReturnNoMemory
;
695 ret
= terminateDriversForModule(name
, unload
);
701 bool IOCatalogue::startMatching( OSDictionary
* matching
)
703 OSCollectionIterator
* iter
;
707 const OSSymbol
* key
;
713 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
714 (void *)gIOProbeScoreKey
);
718 iter
= OSCollectionIterator::withCollection(personalities
);
727 while ((key
= (const OSSymbol
*) iter
->getNextObject()))
729 array
= (OSArray
*) personalities
->getObject(key
);
730 if (array
) for (idx
= 0; (dict
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
732 /* This comparison must be done with only the keys in the
733 * "matching" dict to enable general matching.
735 if (dict
->isEqualTo(matching
, matching
)) {
736 set
->setObject(dict
);
741 // Start device matching.
742 if ( set
->getCount() > 0 ) {
743 IOService::catalogNewDrivers(set
);
747 IORWLockUnlock(lock
);
755 void IOCatalogue::reset(void)
757 IOCatalogue::resetAndAddDrivers(/* no drivers; true reset */ NULL
,
758 /* doMatching */ false);
762 bool IOCatalogue::resetAndAddDrivers(OSArray
* drivers
, bool doNubMatching
)
765 OSArray
* newPersonalities
= NULL
; // do not release
766 OSCollectionIterator
* iter
= NULL
; // must release
767 OSOrderedSet
* matchSet
= NULL
; // must release
768 const OSSymbol
* key
;
770 OSDictionary
* thisNewPersonality
= NULL
; // do not release
771 OSDictionary
* thisOldPersonality
= NULL
; // do not release
772 signed int idx
, newIdx
;
775 newPersonalities
= OSDynamicCast(OSArray
, drivers
);
776 if (!newPersonalities
) {
780 matchSet
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
781 (void *)gIOProbeScoreKey
);
785 iter
= OSCollectionIterator::withCollection(personalities
);
793 IOLog("Resetting IOCatalogue.\n");
795 /* No goto finish from here to unlock.
799 while ((key
= (const OSSymbol
*) iter
->getNextObject()))
801 array
= (OSArray
*) personalities
->getObject(key
);
802 if (!array
) continue;
803 for (idx
= 0; (thisOldPersonality
= (OSDictionary
*) array
->getObject(idx
)); idx
++)
805 if (thisOldPersonality
->getObject("KernelConfigTable")) continue;
806 if (newPersonalities
)
808 (thisNewPersonality
= (OSDictionary
*) newPersonalities
->getObject(newIdx
));
811 /* Unlike in other functions, this comparison must be exact!
812 * The catalogue must be able to contain personalities that
813 * are proper supersets of others.
814 * Do not compare just the properties present in one driver
815 * personality or the other.
817 if (OSDynamicCast(OSDictionary
, thisNewPersonality
) == NULL
) {
818 /* skip thisNewPersonality if it is not an OSDictionary */
821 if (thisNewPersonality
->isEqualTo(thisOldPersonality
))
824 if (thisNewPersonality
)
827 newPersonalities
->removeObject(newIdx
);
831 // not in new set - remove
832 // only remove dictionary if this module in not loaded - 9953845
833 if ( isModuleLoaded(thisOldPersonality
) == false )
835 if (matchSet
) matchSet
->setObject(thisOldPersonality
);
836 array
->removeObject(idx
);
845 (thisNewPersonality
= (OSDictionary
*) newPersonalities
->getObject(newIdx
));
848 if (OSDynamicCast(OSDictionary
, thisNewPersonality
) == NULL
) {
849 /* skip thisNewPersonality if it is not an OSDictionary */
853 OSKext::uniquePersonalityProperties(thisNewPersonality
);
854 addPersonality(thisNewPersonality
);
855 matchSet
->setObject(thisNewPersonality
);
858 /* Finally, start device matching on all new & removed personalities.
860 if (result
&& doNubMatching
&& (matchSet
->getCount() > 0)) {
861 IOService::catalogNewDrivers(matchSet
);
865 IORWLockUnlock(lock
);
868 if (matchSet
) matchSet
->release();
869 if (iter
) iter
->release();
874 bool IOCatalogue::serialize(OSSerialize
* s
) const
879 return super::serialize(s
);
882 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
884 kern_return_t kr
= kIOReturnSuccess
;
888 case kIOCatalogGetContents
:
889 kr
= KERN_NOT_SUPPORTED
;
892 case kIOCatalogGetModuleDemandList
:
893 kr
= KERN_NOT_SUPPORTED
;
896 case kIOCatalogGetCacheMissList
:
897 kr
= KERN_NOT_SUPPORTED
;
900 case kIOCatalogGetROMMkextList
:
901 kr
= KERN_NOT_SUPPORTED
;
905 kr
= kIOReturnBadArgument
;
913 #pragma mark Obsolete Kext Loading Stuff
915 /*********************************************************************
916 **********************************************************************
917 *** BINARY COMPATIBILITY SECTION ***
918 **********************************************************************
919 **********************************************************************
920 * These functions are no longer used are necessary for C++ binary
921 * compatibility on i386.
922 **********************************************************************/