X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/ff6e181ae92fc6f1e89841290f461d1f2f9badd9..cf7d32b81c573a0536dc4da4157f9c26f8d0bed3:/iokit/bsddev/IOKitBSDInit.cpp diff --git a/iokit/bsddev/IOKitBSDInit.cpp b/iokit/bsddev/IOKitBSDInit.cpp index b6c40a4b0..6346d0c2d 100644 --- a/iokit/bsddev/IOKitBSDInit.cpp +++ b/iokit/bsddev/IOKitBSDInit.cpp @@ -1,14 +1,19 @@ /* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_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. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * 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 @@ -18,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #include #include @@ -31,12 +36,14 @@ extern "C" { #include #include +#include // how long to wait for matching root device, secs #define ROOTDEVICETIMEOUT 60 extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys); extern dev_t mdevlookup(int devid); +extern void mdevremoveall(void); kern_return_t IOKitBSDInit( void ) @@ -116,10 +123,10 @@ OSDictionary * IONetworkMatching( const char * path, len = strlen( kIODeviceTreePlane ":" ); maxLen -= len; - if( maxLen < 0) + if( maxLen <= 0) continue; - strcpy( buf, kIODeviceTreePlane ":" ); + strlcpy( buf, kIODeviceTreePlane ":", len + 1 ); comp = buf + len; // remove parameters following ':' from the path @@ -129,10 +136,9 @@ OSDictionary * IONetworkMatching( const char * path, len = skip - path; maxLen -= len; - if( maxLen < 0) + if( maxLen <= 0) continue; - strncpy( comp, path, len ); - comp[ len ] = 0; + strlcpy( comp, path, len + 1 ); matching = IOService::serviceMatching( "IONetworkInterface" ); if( !matching) @@ -162,7 +168,8 @@ OSDictionary * IONetworkNamePrefixMatching( const char * prefix ) OSDictionary * matching; OSDictionary * propDict = 0; const OSSymbol * str = 0; - + char networkType[128]; + do { matching = IOService::serviceMatching( "IONetworkInterface" ); if ( matching == 0 ) @@ -180,6 +187,18 @@ OSDictionary * IONetworkNamePrefixMatching( const char * prefix ) str->release(); str = 0; + // see if we're contrained to netroot off of specific network type + if(PE_parse_boot_argn( "network-type", networkType, 128 )) + { + str = OSSymbol::withCString( networkType ); + if(str) + { + propDict->setObject( "IONetworkRootType", str); + str->release(); + str = 0; + } + } + if ( matching->setObject( gIOPropertyMatchKey, (OSObject *) propDict ) != true ) continue; @@ -260,6 +279,7 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) long partition = -1; long lun = -1; char c; + int len; // scan the tail of the path for "@unit:partition" do { @@ -297,34 +317,52 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen ) if( c || unit == -1 || partition == -1) continue; - maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); - maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path); - maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" ); + len = strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); + maxLen -= len; + if( maxLen <= 0) + continue; - if( maxLen > 0) { - sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); - comp = buf + strlen( buf ); - - if( alias) { - strcpy( comp, alias ); - comp += strlen( alias ); - } - - if ( (look - path)) { - strncpy( comp, path, look - path); - comp += look - path; - } + snprintf( buf, len + 1, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" ); + comp = buf + len; + + if( alias) { + len = strlen( alias ); + maxLen -= len; + if( maxLen <= 0) + continue; + + strlcpy( comp, alias, len + 1 ); + comp += len; + } + + if ( (look - path)) { + len = (look - path); + maxLen -= len; + if( maxLen <= 0) + continue; + + strlcpy( comp, path, len + 1 ); + comp += len; + } - if ( lun != -1 ) - { - sprintf ( comp, "/@%lx,%lx:%ld';}", unit, lun, partition ); - } - else - { - sprintf( comp, "/@%lx:%ld';}", unit, partition ); - } - } else - continue; + if ( lun != -1 ) + { + len = strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" ); + maxLen -= len; + if( maxLen <= 0) + continue; + + snprintf( comp, len + 1, "/@%lx,%lx:%ld';}", unit, lun, partition ); + } + else + { + len = strlen( "/@hhhhhhhh:dddddddddd';}" ); + maxLen -= len; + if( maxLen <= 0) + continue; + + snprintf( comp, len + 1, "/@%lx:%ld';}", unit, partition ); + } return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) ); @@ -351,18 +389,17 @@ OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen ) len = strlen( kIODeviceTreePlane ":" ); maxLen -= len; - if( maxLen < 0) + if( maxLen <= 0) continue; - strcpy( buf, kIODeviceTreePlane ":" ); + strlcpy( buf, kIODeviceTreePlane ":", len + 1 ); comp = buf + len; len = strlen( path ); maxLen -= len; - if( maxLen < 0) + if( maxLen <= 0) continue; - strncpy( comp, path, len ); - comp[ len ] = 0; + strlcpy( comp, path, len + 1 ); matching = OSDictionary::withCapacity( 1 ); if( !matching) @@ -422,7 +459,7 @@ IOService * IOFindMatchingChild( IOService * service ) static int didRam = 0; -kern_return_t IOFindBSDRoot( char * rootName, +kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize, dev_t * root, u_int32_t * oflags ) { mach_timespec_t t; @@ -435,7 +472,7 @@ kern_return_t IOFindBSDRoot( char * rootName, UInt32 *ramdParms = 0; UInt32 flags = 0; - int minor, major; + int mnr, mjr; bool findHFSChild = false; char * mediaProperty = 0; char * rdBootVar; @@ -460,12 +497,20 @@ kern_return_t IOFindBSDRoot( char * rootName, return( kIOReturnNoMemory ); rdBootVar = str + kMaxPathBuf; - if (!PE_parse_boot_arg("rd", rdBootVar ) - && !PE_parse_boot_arg("rootdev", rdBootVar )) + if (!PE_parse_boot_argn("rd", rdBootVar, kMaxBootVar ) + && !PE_parse_boot_argn("rootdev", rdBootVar, kMaxBootVar )) rdBootVar[0] = 0; do { if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) { + data = OSDynamicCast(OSData, regEntry->getProperty( "root-matching" )); + if (data) { + matching = OSDynamicCast(OSDictionary, OSUnserializeXML((char *)data->getBytesNoCopy())); + if (matching) { + continue; + } + } + data = (OSData *) regEntry->getProperty( "boot-uuid" ); if( data) { uuidStr = (const char*)data->getBytesNoCopy(); @@ -565,10 +610,12 @@ kern_return_t IOFindBSDRoot( char * rootName, // from OpenFirmware path IOLog("From path: \"%s\", ", look); - if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) { - matching = IONetworkMatching( look, str, kMaxPathBuf ); - } else { - matching = IODiskMatching( look, str, kMaxPathBuf ); + if (!matching) { + if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) { + matching = IONetworkMatching( look, str, kMaxPathBuf ); + } else { + matching = IODiskMatching( look, str, kMaxPathBuf ); + } } } @@ -590,7 +637,7 @@ kern_return_t IOFindBSDRoot( char * rootName, uuid = (char *)IOMalloc( kMaxBootVar ); if ( uuid ) { - if (!PE_parse_boot_arg( "boot-uuid", uuid )) { + if (!PE_parse_boot_argn( "boot-uuid", uuid, kMaxBootVar )) { panic( "rd=uuid but no boot-uuid= specified" ); } uuidString = OSString::withCString( uuid ); @@ -609,8 +656,9 @@ kern_return_t IOFindBSDRoot( char * rootName, } if( !matching) { - OSString * astring; - // any HFS + OSString * astring; + // Match any HFS media + matching = IOService::serviceMatching( "IOMedia" ); astring = OSString::withCStringNoCopy("Apple_HFS"); if ( astring ) { @@ -670,11 +718,11 @@ kern_return_t IOFindBSDRoot( char * rootName, IOService * subservice = IOFindMatchingChild( service ); if ( subservice ) service = subservice; } else if ( service && mediaProperty ) { - service = service->getProperty(mediaProperty); + service = (IOService *)service->getProperty(mediaProperty); } - major = 0; - minor = 0; + mjr = 0; + mnr = 0; // If the IOService we matched to is a subclass of IONetworkInterface, // then make sure it has been registered with BSD and has a BSD name @@ -695,13 +743,13 @@ kern_return_t IOFindBSDRoot( char * rootName, iostr = (OSString *) service->getProperty( kIOBSDNameKey ); if( iostr) - strcpy( rootName, iostr->getCStringNoCopy() ); + strlcpy( rootName, iostr->getCStringNoCopy(), rootNameSize ); off = (OSNumber *) service->getProperty( kIOBSDMajorKey ); if( off) - major = off->unsigned32BitValue(); + mjr = off->unsigned32BitValue(); off = (OSNumber *) service->getProperty( kIOBSDMinorKey ); if( off) - minor = off->unsigned32BitValue(); + mnr = off->unsigned32BitValue(); if( service->metaCast( "IONetworkInterface" )) flags |= 1; @@ -709,17 +757,17 @@ kern_return_t IOFindBSDRoot( char * rootName, } else { IOLog( "Wait for root failed\n" ); - strcpy( rootName, "en0"); + strlcpy( rootName, "en0", rootNameSize ); flags |= 1; } IOLog( "BSD root: %s", rootName ); - if( major) - IOLog(", major %d, minor %d\n", major, minor ); + if( mjr) + IOLog(", major %d, minor %d\n", mjr, mnr ); else IOLog("\n"); - *root = makedev( major, minor ); + *root = makedev( mjr, mnr ); *oflags = flags; IOFree( str, kMaxPathBuf + kMaxBootVar ); @@ -743,6 +791,25 @@ iofrootx: return( kIOReturnSuccess ); } +void IOSecureBSDRoot(const char * rootName) +{ +#if CONFIG_EMBEDDED + IOReturn result; + IOPlatformExpert *pe; + const OSSymbol *functionName = OSSymbol::withCStringNoCopy("SecureRootName"); + + while ((pe = IOService::getPlatform()) == 0) IOSleep(1 * 1000); + + // Returns kIOReturnNotPrivileged is the root device is not secure. + // Returns kIOReturnUnsupported if "SecureRootName" is not implemented. + result = pe->callPlatformFunction(functionName, false, (void *)rootName, (void *)0, (void *)0, (void *)0); + + functionName->release(); + + if (result == kIOReturnNotPrivileged) mdevremoveall(); +#endif +} + void * IOBSDRegistryEntryForDeviceTree(char * path) { @@ -774,4 +841,20 @@ IOBSDRegistryEntryGetData(void * entry, char * property_name, return (NULL); } +kern_return_t IOBSDGetPlatformUUID( uuid_t uuid, mach_timespec_t timeout ) +{ + IOService * resources; + OSString * string; + + resources = IOService::waitForService( IOService::resourceMatching( kIOPlatformUUIDKey ), &timeout ); + if ( resources == 0 ) return KERN_OPERATION_TIMED_OUT; + + string = ( OSString * ) IOService::getPlatform( )->getProvider( )->getProperty( kIOPlatformUUIDKey ); + if ( string == 0 ) return KERN_NOT_SUPPORTED; + + uuid_parse( string->getCStringNoCopy( ), uuid ); + + return KERN_SUCCESS; +} + } /* extern "C" */