Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct...

21
Processor Privilege- Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels

Transcript of Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct...

Page 1: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Processor Privilege-Levels

How the x86 processor accomplishes transitions among its four distinct privilege-levels

Page 2: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Rationale

• The usefulness of protected-mode derives from its ability to enforce restrictions upon software’s freedom to take certain actions

• Four distinct privilege-levels are supported

• Organizing concept is “concentric rings”

• Innermost ring has greatest privileges, and privileges diminish as rings move outward

Page 3: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Four Privilege Rings

Ring 3

Ring 2

Ring 1

Ring 0

Least-trusted level

Most-trusted level

Page 4: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Suggested purposes

Ring0: operating system kernel

Ring1: operating system services

Ring2: custom extensions

Ring3: ordinary user applications

Page 5: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Unix/Linux and Windows

Ring0: operating system

Ring1: unused

Ring2: unused

Ring3: application programs

Page 6: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Legal Ring-Transitions

• A transition from an outer ring to an inner ring is made possible by using a special control-structure (known as a ‘call gate’)

• The ‘gate’ is defined via a data-structure located in a ‘system’ memory-segment normally not accessible for modifications

• A transition from an inner ring to an outer ring is not nearly so strictly controlled

Page 7: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Data-sharing

• Function-calls typically require that two separate routines share some data-values (e.g., parameter-values get passed from the calling routine to the called routine)

• To support reentrancy and recursion, the processor’s stack-segment is frequently used as a ‘shared-access’ storage-area

• But among routines with different levels of privilege this could create a “security hole”

Page 8: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

An example senario

• Say a procedure that executes in ring 3 calls a procedure that executes in ring 2

• The ring 2 procedure uses a portion of its stack-area to create ‘automatic’ variables that it uses for temporary workspace

• Upon return, the ring 3 procedure would be able to examine whatever values are left behind in this ring 2 workspace

Page 9: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Data Isolation

• To guard against unintentional sharing of privileged information, different stacks are provided at each distinct privilege-level

• Accordingly, any transition from one ring to another must necessarily be accompanied by an mandatory ‘stack-switch’ operation

• The CPU provides for automatic switching of stacks and copying of parameter-values

Page 10: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Call-Gate Descriptors

offset[ 31..16 ]

code-selector offset[ 15..0 ]

gatetype

P 0DPL

parametercount

63 32

31 0

Legend:

P=present (1=yes, 0=no) DPL=Descriptor Prvilege Level (0,1,2,3)code-selector (specifies memory-segment containing procedure code)offset (specifies the procedure’s entry-point within its code-segment)parameter count (specifies how many parameter-values will be copied)gate-type (‘0x4’ means a 16-bit call-gate, ‘0xC’ means a 32-bit call-gate)

Page 11: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

• When a lesser privileged routine wants to invoke a more privileged routine, it does so by using a ‘far call’ machine-instruction (also known as a “long call” in the GNU assembler’s terminology)

• In ‘as’ assembly language:

lcall $callgate-selector, $0

An Interprivilege Call

0x9A (ignored) callgate-selector

opcode offset-field segment-field

Page 12: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

What does the CPU do?

• When CPU fetches a far-call instruction, it will use that instruction’s ‘selector’ value to look up a descriptor in the GDT (or in the current LDT)

• If it’s a ‘call-gate’ descriptor, and if access is allowed (i.e., if CPL DPL), then the CPU will perform a complex sequence of actions which will accomplish the requested ‘ring-transition’

• CPL (Current Privilege Level) is based on least significant 2-bits in register CS (also in SS)

Page 13: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Sequence of CPU’s actions

- pushes the current SS:SP register-values onto a new stack-segment

- copies the specified number of parameters from the old stack onto the new stack

- pushes the updated CS:IP register-values onto the new stack

- loads new values into registers CS:IP (from the callgate-descriptor) and into SS:SP

Page 14: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

The missing info?

• Where do the new values for SS:SP come from? (They’re not found in the call-gate)

• They’re from a special system-segment, known as the TSS (Task State Segment)

• The CPU locates its TSS by referring to the value in register TR (Task Register)

Page 15: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Diagram of the relationships

TASKSTATE

SEGMENT

NEWSTACK

SEGMENT

stack-pointer

OLDSTACK

SEGMENT

params

params

SS:SP

Descriptor-Table

gate-descriptor

call-instruction

TSS-descriptor TR

CS:IP

GDTR

old code-segment new code-segment

called procedure

Page 16: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Return to an Outer Ring

• Use the far-return instruction: ‘lret’ – Restores CS:IP from the current stack– Restores SS:SP from the current stack

• Or use the far-return instruction: ‘lret $n’– Restores CS:IP from the current stack– Discards n parameter-bytes from that stack– Restores SS:SP from that current stack

Page 17: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Demo-program: ‘tryring1.s’

• We have created a short program to show how this ring-transition mechanism works

• It enters protected-mode (at ring0)

• It ‘returns’ to a procedure in ring1

• Procedure shows a confirmation-message

• The ring1 procedure then ‘calls’ to ring0

• The ring0 procedure exits protected-mode

Page 18: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

Data-structures needed

• Global Descriptor Table needs to contain the protected-mode segment-descriptors and also the ‘call-gate’ descriptor– Code-segments for Ring0 and Ring1– Stack-segments for Ring0 and Ring1– Data-segment (for Ring1 to write to VRAM)– Task-State Segment (for the ring0 SS:SP)– Call-Gate Descriptor (for the ‘lcall’ to ring0)

Page 19: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

In-class Exercise #1

• Modify the ‘tryring1.s’ demo so that it uses a 32-bit call-gate and a 32-bit TSS

TSS for 80286 (16-bits)

0

2

4SP1

SP2

SS2

6

8

10

12

SP0

SS0

SS1

ESP0

ESP1

ESP2

SS0

SS1

SS2

TSS for 80386 (32-bits)

0

4

8

12

16

20

24… …

Page 20: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

System Segment-Descriptors

Base[ 15..0 ] Limit[ 15..0 ]

reserved=0

Limit[19..16]

Base[ 31..24 ] Base[ 23..16 ]typeDPL

P 0

Type-codes for system-segments:

0 = reserved 1 = 16-bit TSS (available) 2 = LDT 3 = 16-bit TSS (busy)

8 = reserved 9 = 32-bit TSS (available) A = reserved B = 32-bit TSS (busy)

S-bit is zero

Page 21: Processor Privilege-Levels How the x86 processor accomplishes transitions among its four distinct privilege-levels.

In-class exercise #2

• Modify the ‘tryring1.s’ demo so that it first enters ring2, then calls to ring1 from ring2 (but returns to ring2), and then finally calls to ring0 in order to exit protected-mode

• How many stack-segments do you need?

• How many code-segment descriptors?

• How many VRAM-segment descriptors?