diff --git a/tests/unit/test_arm.c b/tests/unit/test_arm.c index b148b204..a4e8072c 100644 --- a/tests/unit/test_arm.c +++ b/tests/unit/test_arm.c @@ -398,6 +398,52 @@ static void test_arm_thumb_smlabb() OK(uc_close(uc)); } +static void test_arm_not_allow_privilege_escalation() +{ + uc_engine *uc; + int r_cpsr, r_sp, r_spsr, r_lr; + // E3C6601F : BIC r6, r6, #&1F + // E3866013 : ORR r6, r6, #&13 + // E121F006 : MSR cpsr_c, r6 ; switch to SVC32 (should be ineffective + // from USR32) E1A00000 : MOV r0,r0 EF000011 : SWI OS_Exit + char code[] = "\x1f\x60\xc6\xe3\x13\x60\x86\xe3\x06\xf0\x21\xe1\x00\x00\xa0" + "\xe1\x11\x00\x00\xef"; + + uc_common_setup(&uc, UC_ARCH_ARM, UC_MODE_ARM, code, sizeof(code) - 1, + UC_CPU_ARM_CORTEX_A9); + + // https://www.keil.com/pack/doc/CMSIS/Core_A/html/group__CMSIS__CPSR.html + r_cpsr = 0x40000013; // SVC32 + OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); + r_spsr = 0x40000013; + OK(uc_reg_write(uc, UC_ARM_REG_SPSR, &r_spsr)); + r_sp = 0x12345678; + OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp)); + r_lr = 0x00102220; + OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr)); + + r_cpsr = 0x40000010; // USR32 + OK(uc_reg_write(uc, UC_ARM_REG_CPSR, &r_cpsr)); + r_sp = 0x0010000; + OK(uc_reg_write(uc, UC_ARM_REG_SP, &r_sp)); + r_lr = 0x0001234; + OK(uc_reg_write(uc, UC_ARM_REG_LR, &r_lr)); + + uc_assert_err( + UC_ERR_EXCEPTION, + uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + + OK(uc_reg_read(uc, UC_ARM_REG_CPSR, &r_cpsr)); + OK(uc_reg_read(uc, UC_ARM_REG_SP, &r_sp)); + OK(uc_reg_read(uc, UC_ARM_REG_LR, &r_lr)); + + OK((r_cpsr & ((1 << 4) - 1)) == 0); // Stay in USR32 + OK(r_lr == 0x1234); + OK(r_sp == 0x10000); + + OK(uc_close(uc)); +} + TEST_LIST = {{"test_arm_nop", test_arm_nop}, {"test_arm_thumb_sub", test_arm_thumb_sub}, {"test_armeb_sub", test_armeb_sub}, @@ -410,4 +456,6 @@ TEST_LIST = {{"test_arm_nop", test_arm_nop}, {"test_arm_usr32_to_svc32", test_arm_usr32_to_svc32}, {"test_arm_v8", test_arm_v8}, {"test_arm_thumb_smlabb", test_arm_thumb_smlabb}, + {"test_arm_not_allow_privilege_escalation", + test_arm_not_allow_privilege_escalation}, {NULL, NULL}}; \ No newline at end of file