Skip to content
This repository has been archived by the owner on Feb 23, 2021. It is now read-only.

Rneri/umip exceptions #125

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

Rneri/umip exceptions #125

wants to merge 23 commits into from

Conversation

xupengfe
Copy link

@xupengfe xupengfe commented Jul 7, 2017

Want to git clone the UMIP to learn, and make some test scripts for UMIP. Thanks!

This is a special flavor of LUV for UMIP. Remove all the unneeded packages.

Signed-off-by: Ricardo Neri <[email protected]>
I need this file to increase the size of the boot partition, whose
size is calculated by the files it contains. The extra space created by
this file makes it easy to add/replace files that are bigger than the
originals.

Signed-off-by: Ricardo Neri <[email protected]>
User-Mode Instruction Prevention (UMIP) is a security feature present in
new Intel Processors. If enabled, it prevents the execution of certain
instructions if the Current Privilege Level (CPL) is greater than 0. If
these instructions were executed while in CPL > 0, user space applications
could have access to system-wide settings such as the global and local
descriptor tables, the task register and the interrupt descriptor table.

These are the instructions covered by UMIP:
* SGDT - Store Global Descriptor Table
* SIDT - Store Interrupt Descriptor Table
* SLDT - Store Local Descriptor Table
* SMSW - Store Machine Status Word
* STR - Store Task Register

If any of these instructions is executed with CPL > 0, a general protection
exception is issued when UMIP is enbled.

This recipe adds two sample user-space programs that exercises all
the possible combinations of memory and register operands for the
aforementioned instructions. This helps to validate the emulation code
for such instuctions within the Linux kernel.

Signed-off-by: Ricardo Neri <[email protected]>
Ideally, we might want to add these patches in the vm86-test recipe. Unfortunately,
such recipe uses the kernel-source directory to build its artifacts. Thus, we have
no option but to apply the patches here.

The first patch contains tests that are representative of UMIP use cases. The
second patch test UMIP emulation extensively by exercising all the possible
combinations of operands and displacement in 16-bit addressing encodings.

Signed-off-by: Ricardo Neri <[email protected]>
When checking for the return values of SMSW, SLDT and STR, we
use memory operands. Thus, the expected return values are 16-bit.
There is no need to use a long lenght field.

This helps us to prevent build warnings such as:

umip_test2.c:262:2: warning: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
  pr_info("====Checking SLDT. Expected value: [0x%lx]====\n", expected_ldt);
  ^

Signed-off-by: Ricardo Neri <[email protected]>

umip_test2.c:262:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
  pr_info("====Checking SLDT. Expected value: [0x%lx]====\n", expected_ldt);
  ^

Signed-off-by: Ricardo Neri <[email protected]>
The family of macros CHECK_ALLreg and CHECK_ALLmem can use operands
of 16, 32 and 64 bits. Thus, the variables we pass should be the
largest of them: longs.

Otherwise, we see warnings such as:

umip_test2.c:252:2: warning: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 6 has type ‘int’ [-Wformat=]
  CHECK_ALLmem("smsw", val, INIT_MSW, expected_msw);
  ^

Signed-off-by: Ricardo Neri <[email protected]>
There were many variables that we don't use. Remove them.

Signed-off-by: Ricardo Neri <[email protected]>
Instead of returning nothing, have the main functions of test
programs to return an integer.

This makes warnings like this go away:

normal_pf.c:58:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
 void main (void)

Signed-off-by: Ricardo Neri <[email protected]>
This function is not used anywhere. Get rid of it.

Signed-off-by: Ricardo Neri <[email protected]>
This makes warning like this go away:

umip_test.c:61:2: warning: format ‘%lx’ expects argument of type
‘long unsigned int’, but argument 2 has type ‘unsigned char *’ [-Wformat=]
  pr_info("Will issue SGDT and save at [0x%lx]\n", val);
  ^

Signed-off-by: Ricardo Neri <[email protected]>
Apparently, it is not sufficient to include sys/syscall.h as it cannot
find the prototype of syscall. Include also unistd.h and make this warning
go away:

umip_ldt_16.c:117:2: warning: implicit declaration of function ‘syscall’
[-Wimplicit-function-declaration]
  ret = syscall(SYS_modify_ldt, 1, &desc, sizeof(desc));
  ^

Signed-off-by: Ricardo Neri <[email protected]>
We meant to check the return value of setup_data_segments. However,
we did not save its return value in the variable we use to print the
error. Correct this and avoid seeing this warning:

umip_test_defs.h:13:23: warning: ‘ret’ may be used uninitialized in
this function [-Wmaybe-uninitialized]
 #define pr_error(...) printf(TEST_ERROR __VA_ARGS__)
                       ^
umip_ldt_64.c:97:6: note: ‘ret’ was declared here
  int ret;
      ^
gcc -Wall -o umip_ldt_64 test_umip_ldt_64.o umip_ldt_64.o

Signed-off-by: Ricardo Neri <[email protected]>
Old compilers will complain that 32-bit longs are too large to contains
64-bit long values. This is true even when they are OR'ed with a 32-bit
mask. Thus, instead of OR'ing the value, take the 32-bit value and use it
fill the most significant bytes of a 64-bit long.

Signed-off-by: Ricardo Neri <[email protected]>
Python appends an L to any long number and Python decides what type
of variable use based on its value. In most of the cases we will not
implicitly deal with longs (i.e., most of the time our variables will
have small values). However, to represent negative numbers we will
rely on 2's complements and thus we will need long variables. To
avoid the trailing L, use a custom my_hex function to convert a number
to its hex representation.

Reported-by: Qian Ouyang <[email protected]>
Signed-off-by: Ricardo Neri <[email protected]>
This option only makes sense when buiding in x86_64 builds for 64-bit
programs. umip_ldt_32 and umip_ldt_16 are 32-bit programs.

Reported-by: Qian Ouyang <[email protected]>
Signed-off-by: Ricardo Neri <[email protected]>
For reasons beyond my comprehension, certain versions of gcc
use esp, not ebp, to refer to automatic variables in main. This
is only true for main. This is a problem for these programs as
they manipulate the stack. Hence, introduce a new function, called
from main, that executes the actual tests.

Reported-by: Qian Ouyang <[email protected]>
Signed-off-by: Ricardo Neri <[email protected]>
We do this for two reasons: a) some versions of gcc use r/esp, not r/ebp,
to reference automatic variables. This has shown to cause problems in
the past if we need to update r/esp. b) more exception handling tests
will be added to this file. This is preparatory work.

Signed-off-by: Ricardo Neri <[email protected]>
Add support in the signal handler for SIGILL.

Signed-off-by: Ricardo Neri <[email protected]>
Add tests to verify that the UMIP-protected instructions generate
a SIGILL when the LOCK instruction prefix is used.

Signed-off-by: Ricardo Neri <[email protected]>
The instructions SGDT and SIDT generate an #UD exception if the
operands are registers. Tests that this actually happens.

Signed-off-by: Ricardo Neri <[email protected]>
In 32-bit programs, the use of null segment selectors should cause
a #GP(0) exception. Verify that this indeed happens.

Signed-off-by: Ricardo Neri <[email protected]>
…imits

When the effective address is outside of the segment limits, a
general protection fault should be issues. Test that this is the case.

Signed-off-by: Ricardo Neri <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants