X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/ff6e181ae92fc6f1e89841290f461d1f2f9badd9..d1ecb069dfe24481e4a83f44cb5217a2b06746d7:/iokit/Kernel/IONVRAM.cpp?ds=sidebyside diff --git a/iokit/Kernel/IONVRAM.cpp b/iokit/Kernel/IONVRAM.cpp index d443def8c..4c51e4457 100644 --- a/iokit/Kernel/IONVRAM.cpp +++ b/iokit/Kernel/IONVRAM.cpp @@ -1,14 +1,19 @@ /* - * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1998-2006 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 @@ -26,6 +31,8 @@ #include #include #include +#include +#include #define super IOService @@ -109,7 +116,7 @@ void IODTNVRAM::registerNVRAMController(IONVRAMController *nvram) freePartitionSize = currentLength; } else { // Construct the partition ID from the signature and name. - sprintf(partitionID, "0x%02x,", + snprintf(partitionID, sizeof(partitionID), "0x%02x,", *(UInt8 *)(_nvramImage + currentOffset)); strncpy(partitionID + 5, (const char *)(_nvramImage + currentOffset + 4), 12); @@ -216,37 +223,35 @@ void IODTNVRAM::sync(void) bool IODTNVRAM::serializeProperties(OSSerialize *s) const { - bool result; + bool result, hasPrivilege; UInt32 variablePerm; const OSSymbol *key; - OSDictionary *dict, *tmpDict = 0; + OSDictionary *dict = 0, *tmpDict = 0; OSCollectionIterator *iter = 0; if (_ofDict == 0) return false; // Verify permissions. - result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege); - if (result != kIOReturnSuccess) { - tmpDict = OSDictionary::withCapacity(1); - if (tmpDict == 0) return false; + hasPrivilege = (kIOReturnSuccess == IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege)); + + tmpDict = OSDictionary::withCapacity(1); + if (tmpDict == 0) return false; - iter = OSCollectionIterator::withCollection(_ofDict); - if (iter == 0) return false; + iter = OSCollectionIterator::withCollection(_ofDict); + if (iter == 0) return false; - while (1) { - key = OSDynamicCast(OSSymbol, iter->getNextObject()); - if (key == 0) break; + while (1) { + key = OSDynamicCast(OSSymbol, iter->getNextObject()); + if (key == 0) break; - variablePerm = getOFVariablePerm(key); - if (variablePerm != kOFVariablePermRootOnly) { - tmpDict->setObject(key, _ofDict->getObject(key)); - } + variablePerm = getOFVariablePerm(key); + if ((hasPrivilege || (variablePerm != kOFVariablePermRootOnly)) && + ( ! (variablePerm == kOFVariablePermKernelOnly && current_task() != kernel_task) )) { + tmpDict->setObject(key, _ofDict->getObject(key)); } dict = tmpDict; - } else { - dict = _ofDict; } - + result = dict->serialize(s); if (tmpDict != 0) tmpDict->release(); @@ -263,11 +268,12 @@ OSObject *IODTNVRAM::getProperty(const OSSymbol *aKey) const if (_ofDict == 0) return 0; // Verify permissions. + variablePerm = getOFVariablePerm(aKey); result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege); if (result != kIOReturnSuccess) { - variablePerm = getOFVariablePerm(aKey); if (variablePerm == kOFVariablePermRootOnly) return 0; } + if (variablePerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return 0; return _ofDict->getObject(aKey); } @@ -296,12 +302,13 @@ bool IODTNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject) if (_ofDict == 0) return false; // Verify permissions. + propPerm = getOFVariablePerm(aKey); result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege); if (result != kIOReturnSuccess) { - propPerm = getOFVariablePerm(aKey); if (propPerm != kOFVariablePermUserWrite) return false; } - + if (propPerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return 0; + // Don't allow creation of new properties on old world machines. if (getPlatform()->getBootROMType() == 0) { if (_ofDict->getObject(aKey) == 0) return false; @@ -360,11 +367,12 @@ void IODTNVRAM::removeProperty(const OSSymbol *aKey) if (_ofDict == 0) return; // Verify permissions. + propPerm = getOFVariablePerm(aKey); result = IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator); if (result != kIOReturnSuccess) { - propPerm = getOFVariablePerm(aKey); if (propPerm != kOFVariablePermUserWrite) return; } + if (propPerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return; // Don't allow removal of properties on old world machines. if (getPlatform()->getBootROMType() == 0) return; @@ -543,7 +551,7 @@ IOReturn IODTNVRAM::writeNVRAMPartition(const OSSymbol *partitionID, return kIOReturnSuccess; } -UInt32 IODTNVRAM::savePanicInfo(UInt8 *buffer, IOByteCount length) +IOByteCount IODTNVRAM::savePanicInfo(UInt8 *buffer, IOByteCount length) { if ((_piImage == 0) || (length <= 0)) return 0; @@ -557,9 +565,15 @@ UInt32 IODTNVRAM::savePanicInfo(UInt8 *buffer, IOByteCount length) *(UInt32 *)_piImage = length; _nvramImageDirty = true; - + /* + * This prevents OF variables from being committed if the system has panicked + */ _systemPaniced = true; - + /* The call to sync() forces the NVRAM controller to write the panic info + * partition to NVRAM. + */ + sync(); + return length; } @@ -657,7 +671,7 @@ IOReturn IODTNVRAM::initOFVariables(void) // Create the 'aapl,panic-info' property if needed. if (_piImage != 0) { propDataLength = *(UInt32 *)_piImage; - if ((propDataLength != 0) && (propDataLength < (_piPartitionSize - 4))) { + if ((propDataLength != 0) && (propDataLength <= (_piPartitionSize - 4))) { propObject = OSData::withBytes(_piImage + 4, propDataLength); _ofDict->setObject(kIODTNVRAMPanicInfoKey, propObject); propObject->release(); @@ -913,6 +927,10 @@ OFVariable gOFVariables[] = { {"security-mode", kOFVariableTypeString, kOFVariablePermUserRead, -1}, {"security-password", kOFVariableTypeData, kOFVariablePermRootOnly, -1}, {"boot-image", kOFVariableTypeData, kOFVariablePermUserWrite, -1}, + {"com.apple.System.fp-state", kOFVariableTypeData, kOFVariablePermKernelOnly, -1}, +#if CONFIG_EMBEDDED + {"backlight-level", kOFVariableTypeData, kOFVariablePermUserWrite, -1}, +#endif {0, kOFVariableTypeData, kOFVariablePermUserRead, -1} }; @@ -1083,31 +1101,30 @@ bool IODTNVRAM::convertObjectToProp(UInt8 *buffer, UInt32 *length, if ((propNameLength + propDataLength + 2) > *length) return false; // Copy the property name equal sign. - sprintf((char *)buffer, "%s=", propName); - buffer += propNameLength + 1; + buffer += snprintf((char *)buffer, *length, "%s=", propName); switch (propType) { case kOFVariableTypeBoolean : if (tmpBoolean->getValue()) { - strcpy((char *)buffer, "true"); + strlcpy((char *)buffer, "true", *length - propNameLength); } else { - strcpy((char *)buffer, "false"); + strlcpy((char *)buffer, "false", *length - propNameLength); } break; case kOFVariableTypeNumber : tmpValue = tmpNumber->unsigned32BitValue(); if (tmpValue == 0xFFFFFFFF) { - strcpy((char *)buffer, "-1"); + strlcpy((char *)buffer, "-1", *length - propNameLength); } else if (tmpValue < 1000) { - sprintf((char *)buffer, "%ld", tmpValue); + snprintf((char *)buffer, *length - propNameLength, "%d", (uint32_t)tmpValue); } else { - sprintf((char *)buffer, "0x%lx", tmpValue); + snprintf((char *)buffer, *length - propNameLength, "0x%x", (uint32_t)tmpValue); } break; case kOFVariableTypeString : - strcpy((char *)buffer, tmpString->getCStringNoCopy()); + strlcpy((char *)buffer, tmpString->getCStringNoCopy(), *length - propNameLength); break; case kOFVariableTypeData : @@ -1200,9 +1217,8 @@ void IODTNVRAM::updateOWBootArgs(const OSSymbol *key, OSObject *value) tmpData = IONew(UInt8, tmpDataLength + 1); if (tmpData == 0) return; - strncpy((char *)tmpData, (const char *)bootCommandData, cnt); - tmpData[cnt] = '\0'; - strcat((char *)tmpData, (const char *)bootArgsData); + cnt -= strlcpy((char *)tmpData, (const char *)bootCommandData, cnt); + strlcat((char *)tmpData, (const char *)bootArgsData, cnt); bootCommand = OSString::withCString((const char *)tmpData); if (bootCommand != 0) { @@ -1228,7 +1244,6 @@ enum { kMaxNVDataLength = 8 }; -#pragma options align=mac68k struct NVRAMProperty { IONVRAMDescriptor header; @@ -1237,7 +1252,6 @@ struct NVRAMProperty UInt8 dataLength; UInt8 data[ kMaxNVDataLength ]; }; -#pragma options align=reset bool IODTNVRAM::searchNVRAMProperty(IONVRAMDescriptor *hdr, UInt32 *where) { @@ -1605,8 +1619,8 @@ IOReturn IODTNVRAM::writeNVRAMPropertyType1(IORegistryEntry *entry, name = entry->getName(gIODTPlane); comp = entry->getLocation(gIODTPlane); - if( comp && (0 == strcmp("pci", name)) - && (0 == strcmp("80000000", comp))) { + if( comp && (0 == strncmp("pci", name, sizeof("pci"))) + && (0 == strncmp("80000000", comp, sizeof("80000000")))) { // yosemite hack comp = "/pci@80000000"; } else {