diff mbox

[edk2,2/2] OvmfPkg: SataControllerDxe: SataControllerStop: fix use after free

Message ID 1461674532-28993-3-git-send-email-lersek@redhat.com
State New
Headers show

Commit Message

Laszlo Ersek April 26, 2016, 12:42 p.m. UTC
It would be possible to remove the UAF without local variables, by calling
SataPrivateData->PciIo->Attributes() before releasing SataPrivateData.

However, by keeping the location of the call (for which temporary
variables are necessary), we continue to match the error path logic in
SataControllerStart(), which is always recommended.

Reported-by: wang xiaofeng <winggundum82@163.com>
Fixes: bcab71413407e61c144994925556725dd65eede9
Cc: wang xiaofeng <winggundum82@163.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>

---
 OvmfPkg/SataControllerDxe/SataController.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

-- 
1.8.3.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox

Patch

diff --git a/OvmfPkg/SataControllerDxe/SataController.c b/OvmfPkg/SataControllerDxe/SataController.c
index e5ee63a0ab63..1f84ad034e5b 100644
--- a/OvmfPkg/SataControllerDxe/SataController.c
+++ b/OvmfPkg/SataControllerDxe/SataController.c
@@ -563,90 +563,95 @@  EFIAPI
 SataControllerStop (
   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
   IN EFI_HANDLE                     Controller,
   IN UINTN                          NumberOfChildren,
   IN EFI_HANDLE                     *ChildHandleBuffer
   )
 {
   EFI_STATUS                        Status;
   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;
   EFI_SATA_CONTROLLER_PRIVATE_DATA  *SataPrivateData;
+  EFI_PCI_IO_PROTOCOL               *PciIo;
+  UINT64                            OriginalPciAttributes;
 
   //
   // Open the produced protocol
   //
   Status = gBS->OpenProtocol (
                   Controller,
                   &gEfiIdeControllerInitProtocolGuid,
                   (VOID **) &IdeInit,
                   This->DriverBindingHandle,
                   Controller,
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
                   );
   if (EFI_ERROR (Status)) {
     return EFI_UNSUPPORTED;
   }
 
   SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (IdeInit);
   ASSERT (SataPrivateData != NULL);
 
+  PciIo                 = SataPrivateData->PciIo;
+  OriginalPciAttributes = SataPrivateData->OriginalPciAttributes;
+
   //
   // Uninstall the IDE Controller Init Protocol from this instance
   //
   Status = gBS->UninstallMultipleProtocolInterfaces (
                   Controller,
                   &gEfiIdeControllerInitProtocolGuid,
                   &(SataPrivateData->IdeInit),
                   NULL
                   );
   if (EFI_ERROR (Status)) {
     return Status;
   }
 
   if (SataPrivateData->DisqualifiedModes != NULL) {
     FreePool (SataPrivateData->DisqualifiedModes);
   }
   if (SataPrivateData->IdentifyData != NULL) {
     FreePool (SataPrivateData->IdentifyData);
   }
   if (SataPrivateData->IdentifyValid != NULL) {
     FreePool (SataPrivateData->IdentifyValid);
   }
   FreePool (SataPrivateData);
 
   //
   // Restore original PCI attributes
   //
-  SataPrivateData->PciIo->Attributes (
-                            SataPrivateData->PciIo,
-                            EfiPciIoAttributeOperationSet,
-                            SataPrivateData->OriginalPciAttributes,
-                            NULL
-                            );
+  PciIo->Attributes (
+           PciIo,
+           EfiPciIoAttributeOperationSet,
+           OriginalPciAttributes,
+           NULL
+           );
 
   //
   // Close protocols opened by Sata Controller driver
   //
   return gBS->CloseProtocol (
                 Controller,
                 &gEfiPciIoProtocolGuid,
                 This->DriverBindingHandle,
                 Controller
                 );
 }
 
 /**
   Calculate the flat array subscript of a (Channel, Device) pair.
 
   @param[in] SataPrivateData  The private data structure corresponding to the
                               SATA controller that attaches the device for
                               which the flat array subscript is being
                               calculated.
 
   @param[in] Channel          The channel (ie. port) number on the SATA
                               controller that the device is attached to.
 
   @param[in] Device           The device number on the channel.
 
   @return  The flat array subscript suitable for indexing DisqualifiedModes,
            IdentifyData, and IdentifyValid.
 **/