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 <[email protected]>
Fixes: bcab71413407e61c144994925556725dd65eede9
Cc: wang xiaofeng <[email protected]>
Cc: Jordan Justen <[email protected]>
Cc: Ruiyu Ni <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
---
 OvmfPkg/SataControllerDxe/SataController.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

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.
 **/
-- 
1.8.3.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to