X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..d7e50217d7adf6e52786a38bcaa4cd698cb9a79e:/iokit/Kernel/IOCatalogue.cpp diff --git a/iokit/Kernel/IOCatalogue.cpp b/iokit/Kernel/IOCatalogue.cpp index f59e56bab..4c8e3b1b5 100644 --- a/iokit/Kernel/IOCatalogue.cpp +++ b/iokit/Kernel/IOCatalogue.cpp @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * 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@ */ @@ -35,6 +38,7 @@ extern "C" { #include #include #include +#include }; #include @@ -283,6 +287,10 @@ OSOrderedSet * IOCatalogue::findDrivers( OSDictionary * matching, IOTakeLock( lock ); kernelTables->reset(); while ( (dict = (OSDictionary *) kernelTables->getNextObject()) ) { + + /* This comparison must be done with only the keys in the + * "matching" dict to enable general searches. + */ if ( dict->isEqualTo(matching, matching) ) set->setObject(dict); } @@ -340,7 +348,14 @@ bool IOCatalogue::addDrivers(OSArray * drivers, // Be sure not to double up on personalities. driver = (OSDictionary *)array->getObject(count); - if ( dict->isEqualTo(driver, driver) ) { + + /* Unlike in other functions, this comparison must be exact! + * The catalogue must be able to contain personalities that + * are proper supersets of others. + * Do not compare just the properties present in one driver + * pesonality or the other. + */ + if ( dict->isEqualTo(driver) ) { array->removeObject(count); break; } @@ -405,6 +420,10 @@ bool IOCatalogue::removeDrivers( OSDictionary * matching, array->flushCollection(); tables->reset(); while ( (dict = (OSDictionary *)tables->getNextObject()) ) { + + /* This comparison must be done with only the keys in the + * "matching" dict to enable general searches. + */ if ( dict->isEqualTo(matching, matching) ) { AddNewImports( set, dict ); continue; @@ -444,7 +463,7 @@ bool IOCatalogue::isModuleLoaded( const char * moduleName ) const return false; // Is the module already loaded? - k_info = kmod_lookupbyname((char *)moduleName); + k_info = kmod_lookupbyname_locked((char *)moduleName); if ( !k_info ) { kern_return_t ret; @@ -493,6 +512,10 @@ bool IOCatalogue::isModuleLoaded( const char * moduleName ) const return false; } + if (k_info) { + kfree(k_info, sizeof(kmod_info_t)); + } + /* Lock wasn't taken if we get here. */ return true; } @@ -537,22 +560,29 @@ void IOCatalogue::moduleHasLoaded( const char * moduleName ) IOReturn IOCatalogue::unloadModule( OSString * moduleName ) const { - kmod_info_t * k_info; + kmod_info_t * k_info = 0; kern_return_t ret; const char * name; ret = kIOReturnBadArgument; if ( moduleName ) { name = moduleName->getCStringNoCopy(); - k_info = kmod_lookupbyname((char *)name); + k_info = kmod_lookupbyname_locked((char *)name); if ( k_info && (k_info->reference_count < 1) ) { if ( k_info->stop && - !((ret = k_info->stop(k_info, 0)) == kIOReturnSuccess) ) + !((ret = k_info->stop(k_info, 0)) == kIOReturnSuccess) ) { + + kfree(k_info, sizeof(kmod_info_t)); return ret; + } ret = kmod_destroy(host_priv_self(), k_info->id); } } + + if (k_info) { + kfree(k_info, sizeof(kmod_info_t)); + } return ret; } @@ -560,7 +590,6 @@ IOReturn IOCatalogue::unloadModule( OSString * moduleName ) const static IOReturn _terminateDrivers( OSArray * array, OSDictionary * matching ) { OSCollectionIterator * tables; - OSCollectionIterator * props; OSDictionary * dict; OSIterator * iter; OSArray * arrayCopy; @@ -579,12 +608,6 @@ static IOReturn _terminateDrivers( OSArray * array, OSDictionary * matching ) UniqueProperties( matching ); - props = OSCollectionIterator::withCollection(matching); - if ( !props ) { - iter->release(); - return kIOReturnNoMemory; - } - // terminate instances. do { iter->reset(); @@ -593,6 +616,10 @@ static IOReturn _terminateDrivers( OSArray * array, OSDictionary * matching ) if ( !dict ) continue; + /* Terminate only for personalities that match the matching dictionary. + * This comparison must be done with only the keys in the + * "matching" dict to enable general matching. + */ if ( !dict->isEqualTo(matching, matching) ) continue; @@ -621,6 +648,12 @@ static IOReturn _terminateDrivers( OSArray * array, OSDictionary * matching ) array->flushCollection(); tables->reset(); while ( (dict = (OSDictionary *)tables->getNextObject()) ) { + + /* Remove from the catalogue's array any personalities + * that match the matching dictionary. + * This comparison must be done with only the keys in the + * "matching" dict to enable general matching. + */ if ( dict->isEqualTo(matching, matching) ) continue; @@ -657,7 +690,7 @@ IOReturn IOCatalogue::terminateDriversForModule( return kIOReturnNoMemory; dict->setObject(kModuleKey, moduleName); - + IOTakeLock( lock ); ret = _terminateDrivers(array, dict); @@ -689,7 +722,7 @@ IOReturn IOCatalogue::terminateDriversForModule( ret = terminateDriversForModule(name, unload); name->release(); - + return ret; } @@ -710,6 +743,10 @@ bool IOCatalogue::startMatching( OSDictionary * matching ) kernelTables->reset(); while ( (dict = (OSDictionary *)kernelTables->getNextObject()) ) { + + /* This comparison must be done with only the keys in the + * "matching" dict to enable general matching. + */ if ( dict->isEqualTo(matching, matching) ) AddNewImports(set, dict); } @@ -851,6 +888,7 @@ kern_return_t IOCatalogue::removeKernelLinker(void) { segment = getsegbynamefromheader( &_mh_execute_header, "__KLD"); if (!segment) { + IOLog("error removing kernel linker: can't find __KLD segment\n"); result = KERN_FAILURE; goto finish; } @@ -859,6 +897,7 @@ kern_return_t IOCatalogue::removeKernelLinker(void) { segment = getsegbynamefromheader( &_mh_execute_header, "__LINKEDIT"); if (!segment) { + IOLog("error removing kernel linker: can't find __LINKEDIT segment\n"); result = KERN_FAILURE; goto finish; }