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

No CPL Checks for Privileged Instructions #28

Closed
ionescu007 opened this issue Aug 30, 2016 · 7 comments
Closed

No CPL Checks for Privileged Instructions #28

ionescu007 opened this issue Aug 30, 2016 · 7 comments

Comments

@ionescu007
Copy link

Hi,

Many exit handlers for privileged instructions, such as XSETBV, MSR, IN/OUT, do not do appropriate checks for CPL and/or IOPL. As such, with HyperPlatform running, guest user-mode code is allowed to bypass ring permissions.

@hzqst
Copy link

hzqst commented Aug 30, 2016

yes, I found that most hypervisors have this problem.

@alexalexroro
Copy link

Well actually if you open the Intel Software Developer Manual Vol3 and go to section "25.1.1 Relative Priority of Faults and VM Exits" you could see that you will not receive VM exits on instructions which fail privilege checks - these will generate GP exceptions.
So there shouldn't be in any hypervisor checks for privilege levels on exits on privileged instructions.

@tandasat
Copy link
Owner

tandasat commented Sep 1, 2016

Hi, Sorry for the delayed reply.

Can you provide sample code and steps to confirm the issue? As @alexalexroro pointed out, my understanding is that privilege check takes place prior to VM-exit, and below code caused STATUS_PRIVILEGED_INSTRUCTION exception regardless of existence of HyperPlatform. It seemed to support my understanding.

#include "stdafx.h"
#include <Windows.h>
#include <intrin.h>
#include <stdio.h>

int main() {
  __try {
    unsigned char c = __inbyte(0);
    printf("__inbyte %02hx\n", c);
  } __except (EXCEPTION_EXECUTE_HANDLER) {
    printf("Exception %08x\n", GetExceptionCode());
  }
  return 0;
}

status_privileged_instruction
Tested on Win7 x64 with 32bit test program with elevated admini privileges.

@ionescu007
Copy link
Author

It appears you're right on Intel systems. On AMD this is not always the case -- for example see https://bugzilla.redhat.com/show_bug.cgi?id=1284941. My bad :)

@tandasat
Copy link
Owner

tandasat commented Sep 1, 2016

No problem.

I am rather curious how you found the bug report. This report made me think that I should not attempt to support AMD systems hastily. Seems straightforward; in fact, lots of details need to be aware of ;)

@esoterix
Copy link

I haven't tested it but it appears you don't do any privilege checks in VmmpHandleDrAccess. Refer to intel manual "25.1.3 Instructions That Cause VM Exits Conditionally":

MOV DR. The MOV DR instruction [...] VM exit [...] takes priority over the following: general-protection exceptions based on privilege level; and invalid-opcode exceptions that occur because CR4.DE=1 and the instruction specified access to DR4 or DR5

Keep in mind that you should not advance the guest instruction pointer when injecting a #GP due to privilege level.

You can verify this by writing a usermode program that uses an instruction such as "mov dr7, 400h".

@tandasat tandasat reopened this Aug 18, 2017
@tandasat
Copy link
Owner

tandasat commented Aug 26, 2018

@esoterix Thanks for flagging this up. Fixed it along with other DR register access improvement with fedf722.

Test code attached: Issue28.zip

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

No branches or pull requests

5 participants