X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/5d5c5d0d5b79ade9a973d55186ffda2638ba2b6e..8a3053a07cee346dca737a5670e546fd26a7c9d6:/iokit/Kernel/IORegistryEntry.cpp diff --git a/iokit/Kernel/IORegistryEntry.cpp b/iokit/Kernel/IORegistryEntry.cpp index f10f82d6a..c4bbb3513 100644 --- a/iokit/Kernel/IORegistryEntry.cpp +++ b/iokit/Kernel/IORegistryEntry.cpp @@ -1,31 +1,29 @@ /* - * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * 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. The rights granted to you under the - * License may not be used to create, or enable the creation or - * redistribution of, unlawful or unlicensed copies of an Apple operating - * system, or to circumvent, violate, or enable the circumvention or - * violation of, any terms of an Apple operating system software license - * agreement. - * - * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * 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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. @@ -56,13 +54,20 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject) #define kIORegPlaneChildSuffix "ChildLinks" #define kIORegPlaneNameSuffix "Name" #define kIORegPlaneLocationSuffix "Location" + #define kIORegPlaneParentSuffixLen (sizeof(kIORegPlaneParentSuffix) - 1) +#define kIORegPlaneChildSuffixLen (sizeof(kIORegPlaneChildSuffix) - 1) +#define kIORegPlaneNameSuffixLen (sizeof(kIORegPlaneNameSuffix) - 1) +#define kIORegPlaneLocationSuffixLen (sizeof(kIORegPlaneLocationSuffix) - 1) + +#define KASLR_IOREG_DEBUG 0 static IORegistryEntry * gRegistryRoot; static OSDictionary * gIORegistryPlanes; const OSSymbol * gIONameKey; const OSSymbol * gIOLocationKey; +const OSSymbol * gIORegistryEntryIDKey; enum { kParentSetIndex = 0, @@ -73,6 +78,10 @@ enum { kIOMaxPlaneName = 32 }; +enum { kIORegistryIDReserved = (1ULL << 32) + 255 }; + +static uint64_t gIORegistryLastID = kIORegistryIDReserved; + class IORegistryPlane : public OSObject { friend class IORegistryEntry; @@ -147,8 +156,12 @@ IORegistryEntry * IORegistryEntry::initialize( void ) && gIORegistryPlanes ); ok = gRegistryRoot->init(); + if (ok) + gRegistryRoot->reserved->fRegistryEntryID = ++gIORegistryLastID; + gIONameKey = OSSymbol::withCStringNoCopy( "IOName" ); gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" ); + gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey ); assert( ok && gIONameKey && gIOLocationKey ); @@ -181,22 +194,21 @@ const IORegistryPlane * IORegistryEntry::makePlane( const char * name ) char key[ kIOMaxPlaneName + 16 ]; char * end; - strncpy( key, name, kIOMaxPlaneName ); - key[ kIOMaxPlaneName ] = 0; - end = key + strlen( name ); + strlcpy( key, name, kIOMaxPlaneName + 1 ); + end = key + strlen( key ); nameKey = OSSymbol::withCString( key); - strcpy( end, kIORegPlaneParentSuffix ); + strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 ); parentKey = OSSymbol::withCString( key); - strcpy( end, kIORegPlaneChildSuffix ); + strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 ); childKey = OSSymbol::withCString( key); - strcpy( end, kIORegPlaneNameSuffix ); + strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 ); pathNameKey = OSSymbol::withCString( key); - strcpy( end, kIORegPlaneLocationSuffix ); + strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 ); pathLocationKey = OSSymbol::withCString( key); plane = new IORegistryPlane; @@ -260,8 +272,20 @@ bool IORegistryEntry::init( OSDictionary * dict ) if( !super::init()) return( false); + if (!reserved) + { + reserved = IONew(ExpansionData, 1); + if (!reserved) + return (false); + bzero(reserved, sizeof(ExpansionData)); + } if( dict) { - dict->retain(); + if (OSCollection::kImmutable & dict->setOptions(0, 0)) { + dict = (OSDictionary *) dict->copyCollection(); + if (!dict) + return (false); + } else + dict->retain(); if( fPropertyTable) fPropertyTable->release(); fPropertyTable = dict; @@ -306,11 +330,14 @@ bool IORegistryEntry::init( IORegistryEntry * old, WLOCK; + reserved = old->reserved; + old->reserved = NULL; + fPropertyTable = old->getPropertyTable(); fPropertyTable->retain(); #ifdef IOREGSPLITTABLES fRegistryTable = old->fRegistryTable; - old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable ); + old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection(); #endif /* IOREGSPLITTABLES */ old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] ); @@ -339,19 +366,11 @@ bool IORegistryEntry::init( IORegistryEntry * old, void IORegistryEntry::free( void ) { - #if DEBUG_FREE -#define msg ": attached at free()" - char buf[ strlen(msg) + 40 ]; - if( registryTable() && gIOServicePlane) { if( getParentSetReference( gIOServicePlane ) || getChildSetReference( gIOServicePlane )) { - - strncpy( buf, getName(), 32); - buf[32] = 0; - strcat( buf, msg ); - IOPanic( buf ); + panic("%s: attached at free()", getName()); } } #endif @@ -364,6 +383,9 @@ void IORegistryEntry::free( void ) registryTable()->release(); #endif /* IOREGSPLITTABLES */ + if (reserved) + IODelete(reserved, ExpansionData, 1); + super::free(); } @@ -506,6 +528,15 @@ IORegistryEntry::removeProperty( const OSSymbol * aKey) PUNLOCK; } +#if KASLR_IOREG_DEBUG +extern "C" { + +bool ScanForAddrInObject(OSObject * theObject, + int indent); + +}; /* extern "C" */ +#endif + bool IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject) { @@ -523,7 +554,18 @@ IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject) ret = getPropertyTable()->setObject( aKey, anObject ); PUNLOCK; - + +#if KASLR_IOREG_DEBUG + if ( anObject && strcmp(kIOKitDiagnosticsKey, aKey->getCStringNoCopy()) != 0 ) { + if (ScanForAddrInObject(anObject, 0)) { + IOLog("%s: IORegistryEntry name %s with key \"%s\" \n", + __FUNCTION__, + getName(0), + aKey->getCStringNoCopy() ); + } + } +#endif + return ret; } @@ -844,10 +886,10 @@ bool IORegistryEntry::getPath( char * path, int * length, OSArray * stack; IORegistryEntry * root; const IORegistryEntry * entry; - IORegistryEntry * parent; + const IORegistryEntry * parent; const OSSymbol * alias; int index; - int len, maxLength, compLen; + int len, maxLength, compLen, aliasLen; char * nextComp; bool ok; @@ -861,80 +903,76 @@ bool IORegistryEntry::getPath( char * path, int * length, len = plane->nameKey->getLength(); if( len >= maxLength) return( false); - strcpy( nextComp, plane->nameKey->getCStringNoCopy()); + strlcpy( nextComp, plane->nameKey->getCStringNoCopy(), len + 1); nextComp[ len++ ] = ':'; nextComp += len; if( (alias = hasAlias( plane ))) { - len += alias->getLength(); + aliasLen = alias->getLength(); + len += aliasLen; ok = (maxLength > len); *length = len; if( ok) - strcpy( nextComp, alias->getCStringNoCopy()); + strlcpy( nextComp, alias->getCStringNoCopy(), aliasLen + 1); return( ok ); } - entry = this; - parent = entry->getParentEntry( plane ); - if( !parent) - // Error if not attached in plane - return( false); - stack = OSArray::withCapacity( getDepth( plane )); - if( !stack) - return( false); + if (!stack) return( false); RLOCK; + parent = entry = this; root = gRegistryRoot->getChildEntry( plane ); - while( parent && (entry != root)) { + while (parent && (parent != root)) + { // stop below root - stack->setObject( (OSObject *) entry ); entry = parent; parent = entry->getParentEntry( plane ); + stack->setObject( (OSObject *) entry ); } - index = stack->getCount(); - ok = true; - - if( 0 == index) { - - *nextComp++ = '/'; - *nextComp = 0; - len++; - - } else while( ok && ((--index) >= 0)) { - - entry = (IORegistryEntry *) stack->getObject((unsigned int) index ); - assert( entry ); - - if( (alias = entry->hasAlias( plane ))) { - len = plane->nameKey->getLength() + 1; - nextComp = path + len; - - compLen = alias->getLength(); - ok = (maxLength > len + compLen); - if( ok) - strcpy( nextComp, alias->getCStringNoCopy()); - } else { - compLen = maxLength - len; - ok = entry->getPathComponent( nextComp + 1, &compLen, plane ); - - if( ok && compLen) { - compLen++; - *nextComp = '/'; + ok = (0 != parent); + if (ok) + { + index = stack->getCount(); + if( 0 == index) { + + *nextComp++ = '/'; + *nextComp = 0; + len++; + + } else while( ok && ((--index) >= 0)) { + + entry = (IORegistryEntry *) stack->getObject((unsigned int) index ); + assert( entry ); + + if( (alias = entry->hasAlias( plane ))) { + len = plane->nameKey->getLength() + 1; + nextComp = path + len; + + compLen = alias->getLength(); + ok = (maxLength > (len + compLen)); + if( ok) + strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1); + } else { + compLen = maxLength - len; + ok = entry->getPathComponent( nextComp + 1, &compLen, plane ); + + if( ok && compLen) { + compLen++; + *nextComp = '/'; + } } - } - if( ok) { - len += compLen; - nextComp += compLen; + if( ok) { + len += compLen; + nextComp += compLen; + } } + *length = len; } - *length = len; - UNLOCK; - stack->release(); return( ok ); @@ -957,14 +995,14 @@ bool IORegistryEntry::getPathComponent( char * path, int * length, else locLen = 0; - ok = ((len + locLen) < maxLength); + ok = ((len + locLen + 1) < maxLength); if( ok) { - strcpy( path, compName ); + strlcpy( path, compName, len + 1 ); if( loc) { path += len; len += locLen; *path++ = '@'; - strcpy( path, loc ); + strlcpy( path, loc, locLen ); } *length = len; } @@ -1125,8 +1163,7 @@ const char * IORegistryEntry::dealiasPath( {} end--; if( (end - path) < kIOMaxPlaneName) { - strncpy( temp, path, end - path ); - temp[ end - path ] = 0; + strlcpy( temp, path, end - path + 1 ); RLOCK; entry = IORegistryEntry::fromPath( "/aliases", plane ); @@ -1169,8 +1206,7 @@ IORegistryEntry * IORegistryEntry::fromPath( // get plane name end = strchr( path, ':' ); if( end && ((end - path) < kIOMaxPlaneName)) { - strncpy( temp, path, end - path ); - temp[ end - path ] = 0; + strlcpy( temp, path, end - path + 1 ); plane = getPlane( temp ); path = end + 1; } @@ -1221,10 +1257,10 @@ IORegistryEntry * IORegistryEntry::fromPath( if( opath && length) { // copy out residual path - len2 = len + strlen( path ); - if( len2 < *length) - strcpy( opath + len, path ); - *length = len2; + len2 = strlen( path ); + if( (len + len2) < *length) + strlcpy( opath + len, path, len2 + 1 ); + *length = (len + len2); } else if( path[0]) // no residual path => must be no tail for success @@ -1558,12 +1594,16 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const const OSSymbol *key; while( (key = (OSSymbol *) iter->getNextObject()) ) { - const char *keysuffix; + size_t keysuffix; // Get a pointer to this keys suffix - keysuffix = key->getCStringNoCopy() - + key->getLength() - kIORegPlaneParentSuffixLen; - if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) { + keysuffix = key->getLength(); + if (keysuffix <= kIORegPlaneParentSuffixLen) + continue; + keysuffix -= kIORegPlaneParentSuffixLen; + if( !strncmp(key->getCStringNoCopy() + keysuffix, + kIORegPlaneParentSuffix, + kIORegPlaneParentSuffixLen + 1) ) { ret = true; break; } @@ -1589,6 +1629,9 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent, WLOCK; + if (!reserved->fRegistryEntryID) + reserved->fRegistryEntryID = ++gIORegistryLastID; + ret = makeLink( parent, kParentSetIndex, plane ); if( (links = parent->getChildSetReference( plane ))) @@ -1629,6 +1672,14 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent, return( ret ); } +uint64_t IORegistryEntry::getRegistryEntryID( void ) +{ + if (reserved) + return (reserved->fRegistryEntryID); + else + return (0); +} + bool IORegistryEntry::attachToChild( IORegistryEntry * child, const IORegistryPlane * plane ) { @@ -1713,8 +1764,11 @@ void IORegistryEntry::detachAbove( const IORegistryPlane * plane ) IORegistryEntry * parent; retain(); - while( (parent = getParentEntry( plane ))) + while( (parent = copyParentEntry( plane ))) + { detachFromParent( parent, plane ); + parent->release(); + } release(); } @@ -1859,7 +1913,7 @@ void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane ) IORegCursor * prev; prev = where; - where = (IORegCursor *) IOMalloc( sizeof( IORegCursor)); + where = (IORegCursor *) IOMalloc( sizeof(IORegCursor)); assert( where); if( where) { @@ -1889,7 +1943,7 @@ bool IORegistryIterator::exitEntry( void ) if( where != &start) { gone = where; where = gone->next; - IOFree( gone, sizeof( IORegCursor)); + IOFree( gone, sizeof(IORegCursor)); return( true); } else @@ -2005,13 +2059,21 @@ OSOrderedSet * IORegistryIterator::iterateAll( void ) return( done); } +#if __LP64__ +OSMetaClassDefineReservedUnused(IORegistryEntry, 0); +OSMetaClassDefineReservedUnused(IORegistryEntry, 1); +OSMetaClassDefineReservedUnused(IORegistryEntry, 2); +OSMetaClassDefineReservedUnused(IORegistryEntry, 3); +OSMetaClassDefineReservedUnused(IORegistryEntry, 4); +OSMetaClassDefineReservedUnused(IORegistryEntry, 5); +#else OSMetaClassDefineReservedUsed(IORegistryEntry, 0); OSMetaClassDefineReservedUsed(IORegistryEntry, 1); OSMetaClassDefineReservedUsed(IORegistryEntry, 2); OSMetaClassDefineReservedUsed(IORegistryEntry, 3); OSMetaClassDefineReservedUsed(IORegistryEntry, 4); OSMetaClassDefineReservedUsed(IORegistryEntry, 5); - +#endif OSMetaClassDefineReservedUnused(IORegistryEntry, 6); OSMetaClassDefineReservedUnused(IORegistryEntry, 7); OSMetaClassDefineReservedUnused(IORegistryEntry, 8);