Skip to content

Commit

Permalink
app/memcmp: support simulation mode via rflags.tf
Browse files Browse the repository at this point in the history
  • Loading branch information
jovanbulck committed May 20, 2024
1 parent 1f139de commit 27ff720
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 30 deletions.
96 changes: 66 additions & 30 deletions app/memcmp/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <signal.h>
#include <unistd.h>
#include "libsgxstep/apic.h"
#include "libsgxstep/cpu.h"
#include "libsgxstep/pt.h"
#include "libsgxstep/sched.h"
#include "libsgxstep/enclave.h"
Expand All @@ -14,10 +15,23 @@
#include <sys/mman.h>

#define MAX_LEN 15
#define DO_STEP 1
#define DO_TIMER_STEP 1
#define DEBUG 0
#define DBG_ENCL 1
#define ANIMATION_DELAY 50000000
#if DO_TIMER_STEP
#define ANIMATION_DELAY 50000000
#else
#define ANIMATION_DELAY 5000
#endif

/*
* NOTE: set DO_TIMER_STEP=0 to _simulate_ a single-stepping attack through the
* x86 hardware trap flag (RFLAGS.TF). Use for demonstration/debugging purposes
* only, as this does _not_ work for SGX debug enclaves(!)
*/
#if !DO_TIMER_STEP
#warning "Using simulated stepping through HW trap flag; will not work for production enclaves!"
#endif

sgx_enclave_id_t eid = 0;
int irq_cnt = 0, do_irq = 0, fault_cnt = 0, trigger_cnt = 0, step_cnt = 0;
Expand All @@ -29,6 +43,10 @@ void *code_adrs, *trigger_adrs;
/* Called before resuming the enclave after an Asynchronous Enclave eXit. */
void aep_cb_func(void)
{
#if !DO_TIMER_STEP
DISABLE_TF;
#endif

#if DEBUG
uint64_t erip = edbgrd_erip() - (uint64_t) get_enclave_base();
info("^^ enclave RIP=%#llx; ACCESSED=%d", erip, ACCESSED(*pte_encl));
Expand Down Expand Up @@ -69,72 +87,87 @@ void aep_cb_func(void)
* enclave instruction.
*
*/
#if DO_STEP
if (do_irq)
{
*pmd_encl = MARK_NOT_ACCESSED( *pmd_encl );
#if DO_TIMER_STEP
apic_timer_irq( SGX_STEP_TIMER_INTERVAL );
}
#else
ENABLE_TF;
#endif
}
}

/* Called upon SIGSEGV caused by untrusted page tables. */
void fault_handler(int signo, siginfo_t * si, void *ctx)
{
ASSERT(fault_cnt++ < 10);

switch ( signo )
{
case SIGSEGV:
ASSERT(fault_cnt++ < 10);

#if DEBUG
info("Caught page fault (base address=%p)", si->si_addr);
#endif

if (si->si_addr == trigger_adrs)
{
#if DEBUG
info("Restoring trigger access rights..");
#endif
ASSERT(!mprotect(trigger_adrs, 4096, PROT_READ | PROT_WRITE));
do_irq = 1;
}
else
{
info("Unknown #PF address!");
}

break;

#if !DO_TIMER_STEP
case SIGTRAP:
#if DEBUG
//info("Caught single-step trap (RIP=%p)\n", si->si_addr);
#endif
break;
#endif

default:
info("Caught unknown signal '%d'", signo);
abort();
}

if (si->si_addr == trigger_adrs)
{
#if DEBUG
info("Restoring trigger access rights..");
#endif
ASSERT(!mprotect(trigger_adrs, 4096, PROT_READ | PROT_WRITE));
do_irq = 1;
}
else
{
info("Unknown #PF address!");
}

// NOTE: return eventually continues at aep_cb_func and initiates
// single-stepping mode.
}

/* ================== ATTACKER INIT/SETUP ================= */

/* Configure and check attacker untrusted runtime environment. */
void attacker_config_runtime(void)
void register_signal_handler(int signo)
{
struct sigaction act, old_act;

ASSERT( !claim_cpu(VICTIM_CPU) );
ASSERT( !prepare_system_for_benchmark(PSTATE_PCT) );
//print_system_settings();

register_enclave_info();
print_enclave_info();

/* Specify #PF handler with signinfo arguments */
memset(&act, sizeof(sigaction), 0);
act.sa_sigaction = fault_handler;
act.sa_flags = SA_RESTART | SA_SIGINFO;

/* Block all signals while the signal is being handled */
sigfillset(&act.sa_mask);
ASSERT(!sigaction( SIGSEGV, &act, &old_act ));
ASSERT(!sigaction( signo, &act, &old_act ));
}

/* Configure and check attacker untrusted runtime environment. */
void attacker_config_runtime(void)
{
ASSERT( !claim_cpu(VICTIM_CPU) );
ASSERT( !prepare_system_for_benchmark(PSTATE_PCT) );
//print_system_settings();

register_enclave_info();
print_enclave_info();
register_signal_handler( SIGSEGV );
}

/* Provoke page fault on enclave entry to initiate single-stepping mode. */
Expand Down Expand Up @@ -184,11 +217,14 @@ int main( int argc, char **argv )
attacker_config_page_table();
register_aep_cb(aep_cb_func);

#if DO_STEP
#if DO_TIMER_STEP
info_event("Establishing user-space APIC/IDT mappings");
map_idt(&idt);
install_kernel_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR);
apic_timer_oneshot(IRQ_VECTOR);
#else
register_signal_handler( SIGTRAP );
set_debug_optin();
#endif

/* 2. Single-step enclaved execution. */
Expand Down
6 changes: 6 additions & 0 deletions libsgxstep/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
#define IA32_APIC_BASE_MSR 0x1b
#define IA32_TSC_DEADLINE_MSR 0x6e0

#define ENABLE_TF \
__asm__ volatile ("pushf\norl $0x100, (%rsp)\npopf\n")

#define DISABLE_TF \
__asm__ volatile ("pushf\nandl $0xfffffeff, (%rsp)\npopf\n")

uint64_t rdtsc_begin( void );
uint64_t rdtsc_end( void );
uint64_t read_flags(void);
Expand Down
1 change: 1 addition & 0 deletions libsgxstep/enclave.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ void register_enclave_info(void)

victim.tcs = (uint64_t) sgx_get_tcs();
victim.aep = (uint64_t) sgx_get_aep();
info("tcs at %lx; aep at %lx", victim.tcs, victim.aep);
ASSERT( victim.tcs >= victim.base && victim.tcs < victim.limit);
ioctl_init = 1;
}
Expand Down

0 comments on commit 27ff720

Please sign in to comment.