Jump to content

EFI Variable Store on Aptio V (Haswell-E and up)


Best Answer vit9696, 06 January 2018 - 01:30 AM

Ok gentlemen, after some reasonably extensive research we were able to mostly understand several problems preventing the users of AMI APTIO have working NVRAM in macOS. As a result we have a reasonably reliable yet dirty solution. As a side issue we suppose we may have discovered a terrible memory corruption issue due to a of AMI APTIO and boot.efi, which we suppose we also fixed.

Some of the information was mentioned in this topic and/or on applelife, we consider it important to give a summary that covers all the details. Especially because during the research the information obtained was very confusing, which led to certain misunderstandings :D.

1. ASUS APTIO IV Z97 Motherboards

Described here: http://www.insanelym...-6#entry2535040

After the disassembling it was discovered that several APTIO IV drivers including the presented one implement a variable whitelist, and disallow writing anything but the variables from the list. It is unclear whether it was intentional or just an logical mistake, but a most reasonable solution will be to just replace the NvramSmi driver with the working one from a previous firmware and reflash.

EFI_GLOBAL_VARIABLE_GUID:
Lang, Timeout, PlatformLang, ConIn, ConOut, ErrOut, BootOrder, BootNext, DriverOrder, HwErrRecSupport, OsIndications, PK, KEK, FTMActiveFlag
EFI_IMAGE_SECURITY_DATABASE_GUID:
db, dbx

2. APTIO V firmwares with working NVRAM

Some APTIO V firmwares (pre-KabyLake at least) do not use a new NVRAM driver implementation, but rely on a driver that can be found on older Z87 or Z77 APTIO IV motherboards. For this reason NVRAM works fine on them. Notably the extensive changelog of the NVRAM driver covers a lot of issues that arose during the development.

Yet it should be noted that once the firmware was upgraded it is no longer possible to use the older driver, like on Z97 motherboards, due to a completely new stack.

3. APTIO V firmwares with not working NVRAM

a) Before explaining the details of the new bugs we have to go back to describing NVRAM issues on APTIO IV.

As everyone knows during the loading process:
- boot.efi discards all the memory that is not EFI_MEMORY_RUNTIME
- boot.efi physically moves EfiRuntimeServicesCode and EfiRuntimeServicesData regions regions to go one by one and zeroes the original area
- boot.efi assigns virtual addresses to EFI_MEMORY_RUNTIME regions
- XNU maps EfiRuntimeServicesCode as RX memory and everything else supplied as RW memory

However, AMI SMM drivers preserve the original physical address of EfiRuntimeServicesData, and use this memory for communication. Since SMM drivers cannot be easily changed, the AptioFix driver prohibits EfiRuntimeServicesData from being moved by marking it as a EfiMemoryMappedIO region.

To our surprise the AptioFix driver does not revert "temporarily" changed types back to EfiRuntimeServicesData before starting XNU, which undesirably leads to VM_MEM_NOT_CACHEABLE | VM_MEM_GUARDED flags being used in the XNU mapping, yet it not known to cause practical issues.

B) What did the original solution not care about?

There exists a certain FlashDriver that exposes AMI_FLASH_PROTOCOL (755B6596-6896-4ba3-B3DD-1C629FD1EA88).
On APTIO IV this protocol is not used after ExitBootServices (if not earlier) by any EFI_RUNTIME_SERVICES, which was proven by RW mapping it without the X bit, yet is part of the EfiRuntimeServicesCode.
It was discovered that on APTIO IV AMI SMM drivers have a physical address of one of the static variables of this driver, and they use this variable for write access during all the three calls to NVRAM-related EFI_RUNTIME_SERVICES (GetVariable/SetVariable/GetNextVariableName).
Therefore it effectively leads to arbitrary memory corruptions (which happen to be used for RW access by XNU and thus do not trigger a kernel panic with a page fault) when invoking any NVRAM procedures.

c) What did APTIO V do?

On APTIO V they appear to have additionally changed the implementation to work via a shared SMM/DXE buffer. However, unlike APTIO IV, which used EfiRuntimeServicesData, this shared buffer become a static variable in some driver too. Once again since SMM uses physical addresses to the buffer, after boot.efi moves the problematic driver, it will no longer is able to communicate with SMM.

For quite some time (probably due to the lack of the hardware) we thought that the problematic driver was the same FlashDriver just like on APTIO IV. However, this is not the case, and on APTIO V it is some other unknown driver. For this reason we prevented the whole EfiRuntimeServicesCode area from being moved just like with EfiRuntimeServicesData. After we mapped all the EfiRuntimeServicesCode memory as RWX in XNU NVRAM started to work fine. As a result we discovered the memory corruption mentioned in ( B) due to WP page faults. Summary follows.

APTIO IV:

FlashDriver RW  EfiRuntimeServicesData & force same address → nvram works
FlashDriver R X EfiRuntimeServicesCode & force same address → write page fault
FlashDriver RWX EfiRuntimeServicesCode & force same address → nvram works
FlashDriver RWX EfiRuntimeServicesData & force same address → nvram works
RTCode      RWX EfiRuntimeServicesCode & force same address → nvram works
APTIO V:

FlashDriver RW  EfiRuntimeServicesData & force same address → nvram does not work
FlashDriver R X EfiRuntimeServicesCode & force same address → write page fault
FlashDriver RWX EfiRuntimeServicesCode & force same address → nvram does not work
FlashDriver RWX EfiRuntimeServicesData & force same address → nvram does not work
RTCode      RWX EfiRuntimeServicesCode & force same address → nvram works
d) What did we do?

Firstly, we prohibited all the EfiRuntimeServicesCode from being moved by boot.efi. It was a tough decision whether to try researching the exact driver not move just it or the entire code area. The choice was made for the latter, because -1- the NVRAM bugs clearly show that AMI APTIO does not support this and -2- if there exist any more write accesses from SMM to DXE we will discover them by triggering a kernel panic (with a WP page fault) instead of just silently corrupting arbitrary memory area.

Secondly, we created dedicated shims for GetVariable/SetVariable/GetNextVariableName which unset the WP bit during the execution of the UEFI code. This is safe to do in an SMP environment, because AppleEFIRuntime kext performs a lock call during any UEFI code calls, and thus effectively disables CPU preemption. On the contrary patching the kernel to map all the UEFI memory as RWX is an unnecessary risk, which is furthermore prone to errors due to instruction changes. It should be noted, that it is not possible to perform memory region protection upgrade from a kext either (vm_protect fails due to maximum protection being set to a too low value).

The relevant changes for OsxAptioFix2 driver and a prebuilt OsxAptioFix2 driver version, which contains the fix:
[attachment=280559:OsxAptioFix2Drv-WTF.zip]

Signed off: Download-Fritz, vit9696, and everyone who shared their wisdom and helped to test
06.01.17 4:30 MSK Go to the full post


  • Please log in to reply
192 replies to this topic

#1
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

I had asked for NVRAM dumps pre-boot (Shell) and post-boot (OS X) a while ago, but I didn't see such dumps yet.

 

EDIT_ Moved from FileVault 2 thread due to Off-Topic.



#2
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

There is probably a problem in NVRAM handling with my config, because I notice that boot items tend to get duplicated (Clover r3899)

 

 

Attached Files



#3
Slice

Slice

    InsanelyMac V.I.P.

  • Local Moderators
  • 6,804 posts
  • Gender:Male
  • Location:Moscow

make 
> dmpstore -all > dmpstoreAll.txt
and show boot.log as well



#4
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

How is a log of the Variable Store going to help if it cannot be used by OS X? o_O

A Memory Map dump is needed.(memmap in Shell, Firmware Memory Map in DarwinDumper).

boot log will only help if AptioFix is loggijng (is it?)



#5
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

I hope these will be helpful.

 

Note that details about the config are available here. I just removed EmuVariableUefi-64.efi and disabled SIP for the purpose of these tests.

 

Attached Files



#6
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

*sigh* Using that -free2000 driver and wondering why Variable Store access doesn't work... Two options.

1) That driver just wipes anything from the kernel base address till 4GB or 8GB (don't remember). Well, I am pretty sure the Variable SMM Communication Buffer is somewhere in that range and just gets purged away.

2) If the range is not purged away, it could be that Aptio V changed from using RT_data for SMM communication (Aptio IV way) to using Reserved (EDK2) way. AptioFix mods the memory map for Reserved regions not to be mapped during RT, which would mean the buffer cannot be used by UEFI.

 

for 1), you cannot do anything, that's just how it is then.

for 2) you could disable the Reserved convesion code (Lib.c "if ((Desc->Attribute & EFI_MEMORY_RUNTIME) != 0 && Desc->Type == EfiReservedMemoryType)"). If this doesn't work, you can also remove the code that follows ("if ((Desc->PhysicalStart < 0xa0000) && (PhysicalEnd >= 0x9e000))"). Obviously don't remove just that, but the entire block.

 

EDIT: Is -Free2000 OSS even?

EDIT2: EDK2 does NOT use Reserved either, remembered it incorrectly.



#7
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

My experience is that my system is more stable with OSXAptioFix2Drv-free2000.efi than with OSXAptioFix2Drv.efi.

In fact, according to the available doc, OSXAptioFix2Drv-free2000.efi should not differ from OSXAptioFixDrv.efi. The change is described in this ticket, but this has already been merged by rehabman in OSXAptioFixDrv.c since r3409.

 

Anyway, according to my earlier tests and reports from multiple Skylake users, the NVRAM issue is present even with OSXAptioFix2Drv.efi. So more investigation seems useful.

I switched back to OSXAptioFix2Drv.efi and performed a new series of dumps that I attach here. If you can clarify this NVRAM issue, it would be much appreciated.

 

 

 

 

 

Attached Files



#8
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

In fact, according to the available doc, OSXAptioFix2Drv-free2000.efi should not differ from OSXAptioFixDrv.efi.

 

Nonsense...

 

The change is described in this ticket, but this has already been merged by rehabman in OSXAptioFixDrv.c since r3409.

 

This is unrelated.

 

Anyway, according to my earlier tests and reports from multiple Skylake users, the NVRAM issue is present even with OSXAptioFix2Drv.efi.

 

Anyone (including you, barijaona), who can boot with stock AptioFix2, try this: https://www.dropbox....ix2Drv.efi?dl=0



#9
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

I'll try it. What change should be expected ?



#10
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

I'll try it. What change should be expected ?

 

Either Variable Store works or it doesn't. :D



#11
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

It does not work (variable does not persist after a reboot).



#12
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

It does not work (variable does not persist after a reboot).

 

Dumps plz



#13
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

The same kind as before ?


Here we are

Attached Files



#14
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

The same kind as before ?


Here we are

 

The dumps look fine... does it work in Windows / Linux?



#15
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

Sorry, neither Windows nor Linux is installed in this box.



#16
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

Try this one: https://www.dropbox....ix2Drv.efi?dl=0

May not boot.



#17
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

It did not boot  ^_^

 

[edit]

The macOS reboot seems to occur just after FakeSMC is loaded.

For the record, a Clover log.

Attached Files



#18
Slice

Slice

    InsanelyMac V.I.P.

  • Local Moderators
  • 6,804 posts
  • Gender:Male
  • Location:Moscow

It did not boot  ^_^

 

[edit]

The macOS reboot seems to occur just after FakeSMC is loaded.

For the record, a Clover log.

Why did you make AppleIntelSKLGraphicsFramebuffer patches if you have no Intel Graphics at all?

Numerous SSDT loaded also will not clear the reason of reboot.



#19
barijaona

barijaona

    InsanelyMac Protégé

  • Members
  • PipPip
  • 52 posts

Why did you make AppleIntelSKLGraphicsFramebuffer patches if you have no Intel Graphics at all?
Numerous SSDT loaded also will not clear the reason of reboot.


I tested first with the IGPU and added the Nvidia card later.

Will test removing these in the evening.

Aside note : I am pretty sure that OSXAptioFix2Drv.-64 efi worsens the reboot problem. I will probably give the latest version of OSXAptioFixDrv.efi a try.

#20
Download-Fritz

Download-Fritz

    ygolohcysp desreveR

  • Developers
  • 909 posts
  • Gender:Not Telling

I tested first with the IGPU and added the Nvidia card later.

Will test removing these in the evening.

Aside note : I am pretty sure that OSXAptioFix2Drv.-64 efi worsens the reboot problem. I will probably give the latest version of OSXAptioFixDrv.efi a try.

 

https://www.dropbox....ix2Drv.efi?dl=0

Might again not boot. If it boots, might be hibernation does not work.







1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users

© 2017 InsanelyMac  |   News  |   Forum  |   Downloads  |   OSx86 Wiki  |   Designed by Ed Gain  |   Logo by irfan  |   Privacy Policy