for (TotalRootBridgeFound = 0, IioResourceMapEntry = 0; TotalRootBridgeFound < HostBridge->RootBridgeCount, IioResourceMapEntry < MaxIIO; IioResourceMapEntry++) {
Comment : improper use of the comma operator in the condition. Let me remind you that this operator has the lowest priority, it calculates the values of both operands, but itself takes the value of the right one. In this case, the condition is completely analogous to IioResourceMapEntry <MaxIIO, and the TotalRootBridgeFound <HostBridge-> RootBridgeCount check, although fulfilled, does not affect the continuation or interruption of the cycle. /** Allocates one or more 4KB pages of type EfiBootServicesData. Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. @param Pages The number of 4 KB pages to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * EFIAPI AllocatePages ( IN UINTN Pages ) { return InternalAllocatePages (EfiRuntimeServicesData, Pages); }
Comment : The code contradicts the comment and allocates EfiRuntimeServicesData memory instead of the implied EfiBootServicesData. The difference between them is that the memory of the second type will be automatically released at the end of the BDS phase, and the memory of the first type must be freed by explicitly calling FreeMem before the end of the aforementioned phase, otherwise it will remain inaccessible for the OS forever. As a result, a seemingly small error can lead to completely incomprehensible memory leaks and the fragmentation of the OS accessible address space. EFI_STATUS OhciSetLsThreshold ( IN USB_OHCI_HC_DEV *Ohc, IN UINT32 Value ) { EFI_STATUS Status; Status = OhciSetOperationalReg (Ohc->PciIo, HC_PERIODIC_START, &Value); return Status; }
Comment : another copy-paste victim, this time the HC_PERIODIC_START bit is set and checked instead of HC_LS_THREASHOLD. for (MatchLang = Languages, (*Offset) = 0; MatchLang != '\0'; (*Offset)++) { // // Seek to the end of current match language. // for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++); if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) { // // Find the current best Language in the supported languages // break; } // // best language match be in the supported language. // ASSERT (*EndMatchLang == ';'); MatchLang = EndMatchLang + 1; }
Comment : as a result of an error with checking the un-denoted pointer, the cycle became infinite, and only the fact that there was a break saves from looping. for (Index = 0; Index < HandleCount; Index++) { FvHandle = HandleBuffer[Index]; ... for (Index = 0; Index < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) { ... } ... for (Index = 0; Index < AprioriEntryCount; Index++) { ... } }
Comment : sample code that works only due to lucky coincidence. HandleCount in the outer loop is almost always equal to 1, in the mSmmFileTypes array, there is also exactly one element at the moment, and AprioriEntryCount is not less than 1, so the outer loop ends. It is clear that a completely different behavior was meant, but copy-paste has its own opinion on this. #define MMAX(a,b) ((a)>(b)?(a):(b)) ... #pragma pack(1) typedef union { uint32_t raw; struct { ... uint32_t tCMD :2; /**< bit [5:4] Command transport duration */ ... } field; } RegDTR1; /**< DRAM Timing Register 1 */ #pragma pack() ... if (mrc_params->ddr_speed == DDRFREQ_800) { Dtr3.field.tXP = MMAX(0, 1 - Dtr1.field.tCMD); } else { Dtr3.field.tXP = MMAX(0, 2 - Dtr1.field.tCMD); }
Comment : the simplest macro and automatic type casting hit back. Since tCMD is a bit field of the uint32_t type, then in condition 0> 1 - tCMD both parts will be automatically converted to uint32_t, which will make it false for any tCMD value. if (mrc_params->ddr_speed == DDRFREQ_800) { Dtr3.field.tXP = Dtr1.field.tCMD > 0 ? 0 : 1 ; } else { Dtr3.field.tXP = Dtr1.field.tCMD > 1 ? 0 : 2 - Dtr1.field.tCMD; }
UINT8 PollCount; ... do { Data = *((volatile UINT32 *) (UINTN)(Addr)); if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0) { Status = EFI_ABORTED; break; } if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0) { Status = EFI_DEVICE_ERROR; break; } if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) { Status = EFI_DEVICE_ERROR; break; } if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0) { Status = EFI_SUCCESS; break; } MicroSecondDelay(TI2C_POLL); PollCount++; if (PollCount >= MAX_STOP_DET_POLL_COUNT) { Status = EFI_TIMEOUT; break; } } while (TRUE);
Comment : The MAX_STOP_DET_POLL_COUNT macro expands to 40,000, and PollCount cannot be greater than 255, resulting in an infinite loop. if ((QNCMmPci32 (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CAP_OFFSET)) && B_QNC_PCIE_LCAP_CPM) != B_QNC_PCIE_LCAP_CPM) { return; }
Comment : instead of the bitwise AND, the logical expression crept into the expression, as a result, the check became useless. if ((QNCMmPci32 (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_CPM) != B_QNC_PCIE_LCAP_CPM) { return; }
return QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG) && HMBOUND_MASK;
Comment : the same as in the previous case, only worse, this time the return value suffered return QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG) & HMBOUND_MASK;
if (Field & (RH_DEV_REMOVABLE || RH_PORT_PWR_CTRL_MASK)) {
Comment : this time there was no luck with a beat OR. if (Field & (RH_DEV_REMOVABLE | RH_PORT_PWR_CTRL_MASK)) {
SerialNumStrLen = StrLen(SerialNumberPtr); if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } ... SKUNumStrLen = StrLen(SKUNumberPtr); if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } ... FamilyStrLen = StrLen(FamilyPtr); if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; }
Comment : copy-paste failed again, damn it. We receive one value, we check another, we have not clear behavior of function. SerialNumStrLen = StrLen(SerialNumberPtr); if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } ... SKUNumStrLen = StrLen(SKUNumberPtr); if (SKUNumStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; } ... FamilyStrLen = StrLen(FamilyPtr); if (FamilyStrLen > SMBIOS_STRING_MAX_LENGTH) { return EFI_UNSUPPORTED; }
Source: https://habr.com/ru/post/258721/
All Articles