summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-11-22 08:16:16 -0800
committerAndy Lutomirski <luto@amacapital.net>2014-11-22 08:16:16 -0800
commitcdf74c9634b42742f4b2c0f8bdb76ffb41d0201f (patch)
tree1d680afbd3c9d07fdc6da891c22a6017b5071447
parentbcddfc53637d20d55bba633f8a2441b27e3f9055 (diff)
downloadmisc-tests-cdf74c9634b42742f4b2c0f8bdb76ffb41d0201f.tar.gz
sigreturn: Test more cases
-rw-r--r--sigreturn.c54
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;
}