diff options
author | Andy Lutomirski <luto@amacapital.net> | 2014-11-22 08:16:16 -0800 |
---|---|---|
committer | Andy Lutomirski <luto@amacapital.net> | 2014-11-22 08:16:16 -0800 |
commit | cdf74c9634b42742f4b2c0f8bdb76ffb41d0201f (patch) | |
tree | 1d680afbd3c9d07fdc6da891c22a6017b5071447 | |
parent | bcddfc53637d20d55bba633f8a2441b27e3f9055 (diff) | |
download | misc-tests-cdf74c9634b42742f4b2c0f8bdb76ffb41d0201f.tar.gz |
sigreturn: Test more cases
-rw-r--r-- | sigreturn.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/sigreturn.c b/sigreturn.c index 4c2d0f6..3bdd6fd 100644 --- a/sigreturn.c +++ b/sigreturn.c @@ -88,11 +88,37 @@ static void setup_ldt(void) .seg_not_present = 0, .useable = 0 }; + const struct user_desc npcode16_desc = { + .entry_number = 3, + .base_addr = (unsigned long)int3, + .limit = 4095, + .seg_32bit = 1, + .contents = 2, /* Code, not conforming */ + .read_exec_only = 0, + .limit_in_pages = 0, + .seg_not_present = 1, + .useable = 0 + }; + const struct user_desc npdata16_desc = { + .entry_number = 4, + .base_addr = (unsigned long)stack16, + .limit = 0xffff, + .seg_32bit = 0, + .contents = 0, /* Data, grow-up */ + .read_exec_only = 0, + .limit_in_pages = 0, + .seg_not_present = 1, + .useable = 0 + }; if (syscall(SYS_modify_ldt, 1, &code16_desc, sizeof code16_desc) != 0) err(1, "modify_ldt"); if (syscall(SYS_modify_ldt, 1, &data16_desc, sizeof data16_desc) != 0) err(1, "modify_ldt"); + if (syscall(SYS_modify_ldt, 1, &npcode16_desc, sizeof npcode16_desc) != 0) + err(1, "modify_ldt"); + if (syscall(SYS_modify_ldt, 1, &npdata16_desc, sizeof npdata16_desc) != 0) + err(1, "modify_ldt"); } static gregset_t initial_regs, requested_regs, resulting_regs; @@ -144,7 +170,7 @@ static void sigusr1(int sig, siginfo_t *info, void *ctx_void) *ssptr(ctx) = sig_ss; ctx->uc_mcontext.gregs[REG_IP] = - (sig_cs == 0x7) ? 0 : (unsigned long)&int3; + (sig_cs == 0x7 || sig_cs == 0x1f) ? 0 : (unsigned long)&int3; ctx->uc_mcontext.gregs[REG_SP] = (unsigned long)0x8badf00d5aadc0deULL; ctx->uc_mcontext.gregs[REG_AX] = 0; @@ -208,6 +234,7 @@ int cs_bitness(unsigned short cs) int find_cs(int bitness) { unsigned short my_cs; + asm ("mov %%cs,%0" : "=r" (my_cs)); if (cs_bitness(my_cs) == bitness) @@ -303,9 +330,9 @@ static int do_test(int cs_bits, bool use_16bit_ss) return nerrs; } -static int test_bad_iret(int cs_bits, unsigned short ss) +static int test_bad_iret(int cs_bits, unsigned short ss, int force_cs) { - int cs = find_cs(cs_bits); + int cs = force_cs == -1 ? find_cs(cs_bits) : force_cs; if (cs == -1) return 0; @@ -329,9 +356,10 @@ static int test_bad_iret(int cs_bits, unsigned short ss) int main() { int total_nerrs = 0; - unsigned short my_cs; + unsigned short my_cs, my_ss; asm volatile ("mov %%cs,%0" : "=r" (my_cs)); + asm volatile ("mov %%ss,%0" : "=r" (my_ss)); setup_ldt(); stack_t stack = { @@ -354,13 +382,19 @@ int main() clearhandler(SIGTRAP); sethandler(SIGSEGV, sigtrap, SA_ONSTACK); - test_bad_iret(64, (2 << 3) | 7); - test_bad_iret(32, (2 << 3) | 7); - test_bad_iret(16, (2 << 3) | 7); + test_bad_iret(64, (2 << 3) | 7, -1); + test_bad_iret(32, (2 << 3) | 7, -1); + test_bad_iret(16, (2 << 3) | 7, -1); + + test_bad_iret(64, my_cs, -1); + test_bad_iret(32, my_cs, -1); + test_bad_iret(16, my_cs, -1); + + /* IRET will fail with #NP */ + test_bad_iret(32, my_ss, (3 << 3) | 7); - test_bad_iret(64, my_cs); - test_bad_iret(32, my_cs); - test_bad_iret(16, my_cs); + /* IRET will fail with #SS */ + test_bad_iret(32, (4 << 3) | 7, -1); return total_nerrs ? 1 : 0; } |