Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mtrr fixes #329

Merged
merged 4 commits into from
Jan 23, 2024
Merged

Mtrr fixes #329

merged 4 commits into from
Jan 23, 2024

Conversation

Mattiwatti
Copy link
Contributor

Description

This PR fixes a number of issues in the MTRR-related code in EptBuildMtrrMap() and EptGetMemoryType(). The changes themselves are thoroughly documented in the commit messages, so please refer to those for more details.

I think most of the things I (hopefully...) fixed were probably medium severity issues at worst, and I wouldn't normally have even noticed them, let alone made a PR, except for commit 580907e, which fixes a critical issue where load vmm was reliably causing my Z790 + i5 13600K machine to become completely unresponsive (i.e. requiring a hard shutdown/power cycle).

Re: the other commits: I am pretty sure these are real fixes for real bugs, but these were mostly just things I noticed while going through the code and attempting to narrow down the cause of the system hang, so I can't speak to their severity. I can't honestly say I've noticed any difference (for better or worse) from them.


Fixes: #..? Possibly #323, but only if that is in fact the same issue I was seeing. There are some discrepancies with this bug description compared to what this PR is fixing that make me doubt this - see my comment for details.

This PR definitely fixes the full system hang in load vmm on my machine, as well as for at least one other person I found who was running into the same issue (also on a Z790 + 13th gen machine).

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Increase the maximum number of MTRRs stored in the EPT state from arbitrary 100 to the architecturally defined maximum possible number of combined variable and fixed range MTRRs (343)
Also fix invalid UTF-8 characters in comment block re: fixed range MTRRs
1. 'TargetMemoryType' is used in this function both as the variable that holds the eventual return value (i.e. it is normally assigned to at least once), but it is simultaneously also read from in the same loop in order to determine whether the current or some previous MTRR entry should take precedence for the address. Therefore, initializing this variable to any value that also happens to be a valid memory caching type can actually have subtle unintended side effects because makes the initial value biased.

Initialize to a sentinel value of -1 to signify 'not found' instead, and only return the default memory type if no applicable MTRR was found for the address.

2. Related to above: use stricter checks w.r.t. memory type precedence rules before actually assigning a value to TargetMemoryType. This allows us to *tentatively* assign write-through in the case of overlapping MTRRs where one specifies write-through and the other write-back. However, continue searching in this case because fixed range and uncacheable type MTRRs both still take precedence.

3. Simplify check for whether an MTRR describes a page or not. We do not need the 'end address' of the requested page to determine this; an MTRR already has a base and end address, so use these to determine whether the page is contained within its range instead.
1. For the same reasons mentioned in 500d0b0 (correctly applying precedence rules when determining the memory caching type for some page), we actually need a complete collection of *all* valid MTRRs, not just those specifying a memory type other than the default.

   The reasoning for this is that while the MTRR's caching type is obviously what EptGetMemoryType() is looking for, the other fields of the MTRRs are still required in order to determine the order of precedence to apply to the MTRRs themselves. Fixed range MTRRs take precedence over variable range MTRRs if enabled, and UC (which is normally also the default non-MTRR type!) takes precedence over other memory types. Even the base and end addresses are required, as these are used to determine whether any MTRRs with conflicting memory types exist with overlapping ranges that both contain the requested page.

2. The last such check removed here was applying similar logic to skip certain MTRRs, but in a way that was more critically broken: because *our* default type (but probably not the CPU's, as reported by IA32_MTRR_DEF_TYPE MSR!) is write-back caching for EPTs(?), any MTRRs specifying write-back were *also* being ignored here and never committed to the global MTRR map.

This commit fixes an issue where 'load vmm' was reliably causing my Intel 13th gen system to become completely unresponsive, requiring a hard shutdown.

Reference: HyperDbg#323
@SinaKarvandi SinaKarvandi merged commit 74d571c into HyperDbg:dev Jan 23, 2024
@SinaKarvandi
Copy link
Member

Thanks a lot for the PR and the detailed explanation. I'm gonna test it with my 12 gen processor and if it is fine, we gonna release a new version (v0.7.2) as this is a critical bug.

@Mattiwatti Mattiwatti deleted the mtrr-fixes branch January 23, 2024 05:21
@Mattiwatti Mattiwatti restored the mtrr-fixes branch January 25, 2024 19:00
@Mattiwatti Mattiwatti deleted the mtrr-fixes branch January 28, 2024 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants