In QemuVideoControllerDriverStart(): - remove redundant zero-initialization of: - Private->Handle (2 locations) - Private->GopDevicePath (when at devpath end)
- remove fields used for error handling only: - PciAttributesSaved - tigthen scope of temporaries: - MmioDesc - AcpiDeviceNode - supplement missing error checks: - AppendDevicePathNode() can fail with out-of-memory (2 locations) - when installing GopDevicePath - retval of QemuVideoGraphicsOutputConstructor() (can justifiedly fail with out-of-resources) - plug leaks on error: - free GopDevicePath (AppendDevicePathNode() allocates dynamically) - uninstall GopDevicePath - free Private->ModeData - call QemuVideoGraphicsOutputDestructor() - uninstall GOP In QemuVideoGraphicsOutputConstructor(), called by Start(): - supplement missing error checks: - QemuVideoGraphicsOutputSetMode() retval (it can fail with out-of-resources) - plug leaks on error: - free Mode->Info - free Mode In QemuVideoCirrusModeSetup() and QemuVideoBochsModeSetup(), both called by Start(): - supplement missing error checks: - AllocatePool() can fail in both In QemuVideoGraphicsOutputDestructor(), called by Start() on the error path: - plug leaks: - free Private->LineBuffer, which is allocated in Start() -> Constructor() -> SetMode() In QemuVideoGraphicsOutputSetMode(), called by Start() indirectly: - remove redundant zero-assignment to: - Private->LineBuffer Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- OvmfPkg/QemuVideoDxe/Driver.c | 207 +++++++++++++++++++++----------------- OvmfPkg/QemuVideoDxe/Gop.c | 23 ++++- OvmfPkg/QemuVideoDxe/Initialize.c | 6 ++ 3 files changed, 140 insertions(+), 96 deletions(-) diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c index b253ec7..b1105f4 100644 --- a/OvmfPkg/QemuVideoDxe/Driver.c +++ b/OvmfPkg/QemuVideoDxe/Driver.c @@ -203,29 +203,23 @@ QemuVideoControllerDriverStart ( { EFI_STATUS Status; QEMU_VIDEO_PRIVATE_DATA *Private; - BOOLEAN PciAttributesSaved; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - ACPI_ADR_DEVICE_PATH AcpiDeviceNode; PCI_TYPE00 Pci; QEMU_VIDEO_CARD *Card; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; EFI_PCI_IO_PROTOCOL *ChildPciIo; - PciAttributesSaved = FALSE; // // Allocate Private context data for GOP inteface. // Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA)); if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; + return EFI_OUT_OF_RESOURCES; } // // Set up context record // Private->Signature = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE; - Private->Handle = NULL; // // Open PCI I/O Protocol @@ -239,7 +233,7 @@ QemuVideoControllerDriverStart ( EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { - goto Error; + goto FreePrivate; } // @@ -253,13 +247,16 @@ QemuVideoControllerDriverStart ( &Pci ); if (EFI_ERROR (Status)) { - goto Error; + goto ClosePciIo; } + // + // Determine card variant. + // Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId); if (Card == NULL) { Status = EFI_DEVICE_ERROR; - goto Error; + goto ClosePciIo; } Private->Variant = Card->Variant; @@ -274,10 +271,12 @@ QemuVideoControllerDriverStart ( ); if (EFI_ERROR (Status)) { - goto Error; + goto ClosePciIo; } - PciAttributesSaved = TRUE; + // + // Set new PCI attributes + // Status = Private->PciIo->Attributes ( Private->PciIo, EfiPciIoAttributeOperationEnable, @@ -285,13 +284,15 @@ QemuVideoControllerDriverStart ( NULL ); if (EFI_ERROR (Status)) { - goto Error; + goto ClosePciIo; } // // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+). // if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) { + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc; + Status = Private->PciIo->GetBarAttributes ( Private->PciIo, PCI_BAR_IDX2, @@ -322,7 +323,7 @@ QemuVideoControllerDriverStart ( if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) { DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId)); Status = EFI_DEVICE_ERROR; - goto Error; + goto RestoreAttributes; } } @@ -335,13 +336,15 @@ QemuVideoControllerDriverStart ( (VOID **) &ParentDevicePath ); if (EFI_ERROR (Status)) { - goto Error; + goto RestoreAttributes; } // // Set Gop Device Path // if (RemainingDevicePath == NULL) { + ACPI_ADR_DEVICE_PATH AcpiDeviceNode; + ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; @@ -352,31 +355,37 @@ QemuVideoControllerDriverStart ( ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode ); + if (Private->GopDevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto RestoreAttributes; + } } else if (!IsDevicePathEnd (RemainingDevicePath)) { // // If RemainingDevicePath isn't the End of Device Path Node, // only scan the specified device by RemainingDevicePath // Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath); - } else { - // - // If RemainingDevicePath is the End of Device Path Node, - // don't create child device and return EFI_SUCCESS - // - Private->GopDevicePath = NULL; + if (Private->GopDevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto RestoreAttributes; + } } - + + // + // Create new child handle and install the device path protocol on it only if + // RemainingDevicePath equals NULL, or doesn't point to the End of Device + // Path Node. + // if (Private->GopDevicePath != NULL) { - // - // Creat child handle and device path protocol firstly - // - Private->Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( &Private->Handle, &gEfiDevicePathProtocolGuid, Private->GopDevicePath, NULL ); + if (EFI_ERROR (Status)) { + goto FreeGopDevicePath; + } } // @@ -397,84 +406,96 @@ QemuVideoControllerDriverStart ( break; } if (EFI_ERROR (Status)) { - goto Error; + goto UninstallGopDevicePath; } + // + // If RemainingDevicePath points to the End of Device Path Node, then we + // haven't created a child handle, and we're done. + // if (Private->GopDevicePath == NULL) { - // - // If RemainingDevicePath is the End of Device Path Node, - // don't create child device and return EFI_SUCCESS - // - Status = EFI_SUCCESS; - } else { + return EFI_SUCCESS; + } - // - // Start the GOP software stack. - // - Status = QemuVideoGraphicsOutputConstructor (Private); - ASSERT_EFI_ERROR (Status); + // + // Start the GOP software stack. + // + Status = QemuVideoGraphicsOutputConstructor (Private); + if (EFI_ERROR (Status)) { + goto FreeModeData; + } - Status = gBS->InstallMultipleProtocolInterfaces ( - &Private->Handle, - &gEfiGraphicsOutputProtocolGuid, - &Private->GraphicsOutput, - NULL - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &ChildPciIo, - This->DriverBindingHandle, - Private->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiGraphicsOutputProtocolGuid, + &Private->GraphicsOutput, + NULL ); - - if (EFI_ERROR (Status)) { - goto Error; - } + if (EFI_ERROR (Status)) { + goto DestructQemuVideoGraphics; } -Error: + // + // Reference parent handle from child handle. + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &ChildPciIo, + This->DriverBindingHandle, + Private->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); if (EFI_ERROR (Status)) { - if (Private) { - if (Private->PciIo) { - if (PciAttributesSaved == TRUE) { - // - // Restore original PCI attributes - // - Private->PciIo->Attributes ( - Private->PciIo, - EfiPciIoAttributeOperationSet, - Private->OriginalPciAttributes, - NULL - ); - } - // - // Close the PCI I/O Protocol - // - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Private->Handle - ); - } - - gBS->FreePool (Private); - } + goto UninstallGop; } + // + // When adding further code that can fail, the error handling label to jump + // to is CloseChildRef. + // + return EFI_SUCCESS; + +#if 0 // in order to suppress the compiler warning about the unused label +CloseChildRef: +#endif + gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, Private->Handle); + +UninstallGop: + gBS->UninstallProtocolInterface (Private->Handle, + &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput); + +DestructQemuVideoGraphics: + QemuVideoGraphicsOutputDestructor (Private); + +FreeModeData: + FreePool (Private->ModeData); + +UninstallGopDevicePath: + // + // Handles the case transparently when Private->Handle and + // Private->GopDevicePath are NULL. + // + gBS->UninstallProtocolInterface (Private->Handle, + &gEfiDevicePathProtocolGuid, Private->GopDevicePath); + +FreeGopDevicePath: + if (Private->GopDevicePath != NULL) { + FreePool (Private->GopDevicePath); + } + +RestoreAttributes: + Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet, + Private->OriginalPciAttributes, NULL); + +ClosePciIo: + gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, Controller); + +FreePrivate: + FreePool (Private); + return Status; } diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c index 30aac7f..1b7db32 100644 --- a/OvmfPkg/QemuVideoDxe/Gop.c +++ b/OvmfPkg/QemuVideoDxe/Gop.c @@ -176,7 +176,6 @@ Routine Description: gBS->FreePool (Private->LineBuffer); } - Private->LineBuffer = NULL; Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution); if (Private->LineBuffer == NULL) { return EFI_OUT_OF_RESOURCES; @@ -321,13 +320,14 @@ QemuVideoGraphicsOutputConstructor ( if (EFI_ERROR (Status)) { return Status; } + Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), (VOID **) &Private->GraphicsOutput.Mode->Info ); if (EFI_ERROR (Status)) { - return Status; + goto FreeMode; } Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode; Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; @@ -337,7 +337,11 @@ QemuVideoGraphicsOutputConstructor ( // // Initialize the hardware // - GraphicsOutput->SetMode (GraphicsOutput, 0); + Status = GraphicsOutput->SetMode (GraphicsOutput, 0); + if (EFI_ERROR (Status)) { + goto FreeInfo; + } + DrawLogo ( Private, Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution, @@ -345,6 +349,15 @@ QemuVideoGraphicsOutputConstructor ( ); return EFI_SUCCESS; + +FreeInfo: + FreePool (Private->GraphicsOutput.Mode->Info); + +FreeMode: + FreePool (Private->GraphicsOutput.Mode); + Private->GraphicsOutput.Mode = NULL; + + return Status; } EFI_STATUS @@ -363,6 +376,10 @@ Returns: --*/ { + if (Private->LineBuffer != NULL) { + FreePool (Private->LineBuffer); + } + if (Private->GraphicsOutput.Mode != NULL) { if (Private->GraphicsOutput.Mode->Info != NULL) { gBS->FreePool (Private->GraphicsOutput.Mode->Info); diff --git a/OvmfPkg/QemuVideoDxe/Initialize.c b/OvmfPkg/QemuVideoDxe/Initialize.c index 305797b..3774478 100644 --- a/OvmfPkg/QemuVideoDxe/Initialize.c +++ b/OvmfPkg/QemuVideoDxe/Initialize.c @@ -176,6 +176,9 @@ QemuVideoCirrusModeSetup ( Private->ModeData = AllocatePool ( sizeof (Private->ModeData[0]) * QEMU_VIDEO_CIRRUS_MODE_COUNT ); + if (Private->ModeData == NULL) { + return EFI_OUT_OF_RESOURCES; + } ModeData = Private->ModeData; VideoMode = &QemuVideoCirrusModes[0]; for (Index = 0; Index < QEMU_VIDEO_CIRRUS_MODE_COUNT; Index ++) { @@ -228,6 +231,9 @@ QemuVideoBochsModeSetup ( Private->ModeData = AllocatePool ( sizeof (Private->ModeData[0]) * QEMU_VIDEO_BOCHS_MODE_COUNT ); + if (Private->ModeData == NULL) { + return EFI_OUT_OF_RESOURCES; + } ModeData = Private->ModeData; VideoMode = &QemuVideoBochsModes[0]; for (Index = 0; Index < QEMU_VIDEO_BOCHS_MODE_COUNT; Index ++) { -- 1.8.3.1 ------------------------------------------------------------------------------ Managing the Performance of Cloud-Based Applications Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. Read the Whitepaper. http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel