Skip to content

Commit

Permalink
Reproduce #GP crash when interrupting kernel code with a user handler.
Browse files Browse the repository at this point in the history
For reference, the following matrix summarizes whether code with
privilege level my_cpl can be interrupted by a handler with privilege
level irq_cpl.

| my_cpl \ irq_cpl | 0  |  3   |
|------------------+----+------|
|                0 | OK | FAIL |
|                3 | OK | OK   |
  • Loading branch information
jovanbulck committed Jul 28, 2020
1 parent 0bac377 commit 56fb7f3
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
45 changes: 36 additions & 9 deletions app/idt/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

#include "libsgxstep/idt.h"
#include "libsgxstep/gdt.h"
#include "libsgxstep/apic.h"
#include "libsgxstep/cpu.h"
#include "libsgxstep/sched.h"
Expand All @@ -27,24 +28,48 @@
#define DO_APIC_TMR_IRQ 1
#define DO_APIC_SW_IRQ 0
#define DO_USER_HANDLER 0
#define DO_USER_LOOP 0

void __ss_irq_handler(void);
extern int volatile __ss_irq_fired, __ss_irq_count, __ss_irq_cpl;

/* ------------------------------------------------------------ */
/* This code may execute with ring0 privileges */
int my_cpl = -1;

void do_irq_loop(void)
{
my_cpl = get_cpl();
__ss_irq_fired = 0;
apic_timer_irq(10);
while(!__ss_irq_fired);
}

void my_ring0_func(void)
{
my_cpl = get_cpl();
}
/* ------------------------------------------------------------ */

int main( int argc, char **argv )
{
idt_t idt = {0};
ASSERT( !claim_cpu(VICTIM_CPU) );

info_event("Establishing user space IDT mapping");
map_idt(&idt);
#if DO_USER_HANDLER
install_user_asm_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR);
#else
install_kernel_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR);
#endif
#if DO_USER_HANDLER
install_user_asm_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR);
#else
install_kernel_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR);
#endif
//dump_idt(&idt);

#if !DO_USER_LOOP
exec_priv(my_ring0_func);
info("back from my_ring0_func w CPL=%d", my_cpl);
#endif

#if DO_APIC_SW_IRQ
info_event("Triggering user space software interrupts");
asm("int %0\n\t" ::"i"(IRQ_VECTOR):);
Expand All @@ -58,10 +83,12 @@ int main( int argc, char **argv )
for (int i=0; i < 3; i++)
{
//apic_send_ipi_self(IRQ_VECTOR);
__ss_irq_fired = 0;
apic_timer_irq(10);
while(!__ss_irq_fired);
info("returned from timer IRQ: CPL=%d; count=%d; flags=%p", __ss_irq_cpl, __ss_irq_count, read_flags());
#if DO_USER_LOOP
do_irq_loop();
#else
exec_priv(do_irq_loop);
#endif
info("returned from timer IRQ: my_cpl=%d; irq_cpl=%d; count=%d; flags=%p", my_cpl, __ss_irq_cpl, __ss_irq_count, read_flags());
}

apic_timer_deadline();
Expand Down
4 changes: 3 additions & 1 deletion libsgxstep/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ void install_kernel_irq_handler(idt_t *idt, void *asm_handler, int vector)
gate->p = 1;
gate->segment = KERNEL_CS;
gate->dpl = USER_DPL;
gate->type = GATE_INTERRUPT;
/* XXX we can also do GATE_INTERRUPT here but then exec_priv code would be uninterruptible */
gate->type = GATE_TRAP;
//gate->type = GATE_INTERRUPT;
gate->ist = 0;

libsgxstep_info("installed ring0 IRQ handler with target_rip=%p", asm_handler);
Expand Down

0 comments on commit 56fb7f3

Please sign in to comment.