-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Unicorn 2 regression: ARM32 mode transition from USR32 to SVC32 in emulated code is allowed (privilege escalation) #1520
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
Comments
Thanks for your report. Would have a look asap. |
This now seems to have broken the CPSR register when mode changes happen - I'll raise a new ticket for this. |
I feel I got something wrong when I modified qemu arm code about exception level and system mode long time ago, which is probably the root cause of the series of your issues. But I couldn’t figure out that exactly now.
Anyway, looking forward to your report and let’s fix it together :)
…________________________________
From: Charles Ferguson ***@***.***>
Sent: Tuesday, January 4, 2022 11:05:00 PM
To: unicorn-engine/unicorn ***@***.***>
Cc: lazymio ***@***.***>; State change ***@***.***>
Subject: Re: [unicorn-engine/unicorn] Unicorn 2 regression: ARM32 mode transition from USR32 to SVC32 in emulated code is allowed (privilege escalation) (Issue #1520)
This now seems to have broken the CPSR register when mode changes happen - I'll raise a new ticket for this.
―
Reply to this email directly, view it on GitHub<#1520 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AHJULO5JZJHKCJWH2WB3YJLUUNVIZANCNFSM5LBO5YPQ>.
You are receiving this because you modified the open/close state.Message ID: ***@***.***>
|
No worries. Hopefully with each example and fix we get closer to getting the right combination. I'm really glad that I've got a pretty reliable OS to be able to test this against, and tests for many of the low level operation (although not the instructions) so that I can find problems. |
(Firstly, thank you for the prior fixes for mode transitions - my OS is getting further through execution now)
Unicorn 2 is allowing the the transition from
USR32
toSVC32
using emulated code.This differs from bug #1500 which was that the operation was disallowed using direct access to the
CPSR
. This bug is where code is being executed in USR32 mode is able to gain privilege by the use of an MSR instruction.The actual problem that I'm hitting in my OS is that I'm in
SVC32
and Unicorn isn't allowing the transition toUSR32
, and investigation showed that theIS_USER()
function believes we're in user mode, but theCPSR
is currently0x60000013
- ie SVC32. The two problems are, I believe related, and theUSR32
->SVC32
privilege escalation is the easier to demonstrate.I think it is the change that is being made in the direct code which isn't updating the state properly.
The consequence of this problem is that whilst my operating system runs some code, depending on the operations performed for mode transitions the system may disallow a mode change in the emulated code which should have been allowed, or vice-versa.
Source environment
I built unicorn on the dev branch at sha cddc9cf.
This is after the fix for #1500 (which relates to corruption inability to change mode in code).
This has been tested on OSX system on Intel hardware (10.14.6)
In order to test this behaviour I have added additional debug which prints the state of registers within functions which were relevant. This code can be found here: https://github.com/gerph/unicorn/tree/cjf-debug-privileged-mode-problems and is shown as a change here: gerph@bda7f29
Failure mode
The failures appears to be that emulated code is able to escalate its privilege to priviledged mode because the state set in the CPSR and the state described by
IS_USER()
are inconsistent. I have been unable to tie down exactly where they're inconsistent, but I believe it's some interaction between the mode that is manipulated by the emulated code and the mode that is manipulated by the direct access in the management code.What are we testing?
We want to set up the state of the system, and observe that we can freely change moves.
Sequence of tests
What is the problem?
The emulated code should not be able to escalate its privilege.
This only seems to happen if the mode has been changed in the controlling python code to USR32 - I believe this state change is not being reflected properly in the variables. If the mode change to USR32 happens within emulated code with an
MSR
, everything is fine.Test code
Test code which exhibits this problem:
Failing output (Unicorn 2)
This produces the following output on Unicorn 2 (failing output) - using my branch which adds additional information about the state of some of the internal state:
The final register dump should have
sp
=0x00010000
, andCPSR
=0x40000010
.At the point of execution (
--- Executing code at 0x00001000
) the register dump shows that that CPSR contains0x40000010
(USR32
mode). However, the debug from within the functionarm_tr_init_disas_context
shows that the internal state still thinks that we're in a privileged mode -current_el
!= 0 and thereforedc->user
is false.It is this state which then allows the subsequent changes of the state to happen. In
msr_mask
there is a checkIS_USER()
which checks the state ofdc->user
and finding that we're in a privileged mode allows the mode change to escalate.Successful output (Unicorn 1)
Does not include the additional debug from the internal state:
Observe that the
CPSR
at the end is correctly set to0x40000010
- the privilege escalation has not happened.The text was updated successfully, but these errors were encountered: