From 9233bcc513a872623e6787a3e52ba97a7b14546f Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 5 Oct 2021 19:06:56 +0200 Subject: [PATCH 1/6] Create stale.yml to activate stale bot. --- .github/stale.yml | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..19a10656 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,59 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 60 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 15 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pinned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: true + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: true + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +# closeComment: > +# Your comment here. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +# only: issues + +# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +# pulls: +# daysUntilStale: 30 +# markComment: > +# This pull request has been automatically marked as stale because it has not had +# recent activity. It will be closed if no further activity occurs. Thank you +# for your contributions. + +# issues: +# exemptLabels: +# - confirmed From 21d3181e000a1090c405bfc604bedcb57f88526a Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 5 Oct 2021 19:29:12 +0200 Subject: [PATCH 2/6] Use action/stale --- .github/workflows/stale.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..d1f6786c --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,20 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 5 * * *' + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v4 + with: + stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.' + days-before-stale: 60 + days-before-close: 15 + exempt-all-milestones: true + exempt-issue-labels: + - pinned + exempt-pr-labels: + - pinned From ad3325548d86991e153ff8fa7971aa255fe3da76 Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 5 Oct 2021 19:30:48 +0200 Subject: [PATCH 3/6] Syntax fixed --- .github/workflows/stale.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index d1f6786c..eb995b0a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,5 @@ jobs: days-before-stale: 60 days-before-close: 15 exempt-all-milestones: true - exempt-issue-labels: - - pinned - exempt-pr-labels: - - pinned + exempt-issue-labels: 'pinned' + exempt-pr-labels: 'pinned' From 3fadb5aa5aad22926f5f816dbe396f8661990374 Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 5 Oct 2021 19:34:19 +0200 Subject: [PATCH 4/6] Delete stale.yml since we are using github official one --- .github/stale.yml | 59 ----------------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 19a10656..00000000 --- a/.github/stale.yml +++ /dev/null @@ -1,59 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 60 - -# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 15 - -# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) -onlyLabels: [] - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: - - pinned - -# Set to true to ignore issues in a project (defaults to false) -exemptProjects: true - -# Set to true to ignore issues in a milestone (defaults to false) -exemptMilestones: true - -# Set to true to ignore issues with an assignee (defaults to false) -exemptAssignees: false - -# Label to use when marking as stale -staleLabel: stale - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. - -# Comment to post when removing the stale label. -# unmarkComment: > -# Your comment here. - -# Comment to post when closing a stale Issue or Pull Request. -# closeComment: > -# Your comment here. - -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 30 - -# Limit to only `issues` or `pulls` -# only: issues - -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -# pulls: -# daysUntilStale: 30 -# markComment: > -# This pull request has been automatically marked as stale because it has not had -# recent activity. It will be closed if no further activity occurs. Thank you -# for your contributions. - -# issues: -# exemptLabels: -# - confirmed From 4059906e78df56f7e457702174615065aea8532a Mon Sep 17 00:00:00 2001 From: Fedor Nis'kov Date: Mon, 6 Dec 2021 19:15:00 +0300 Subject: [PATCH 5/6] Bug fix for LUI instruction (MIPS) --- qemu/target-mips/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 9a3ac9e8..aaa76f4a 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -2551,7 +2551,7 @@ static void gen_logic_imm(DisasContext *ctx, uint32_t opc, tcg_gen_ext32s_tl(tcg_ctx, *cpu_gpr[rt], *cpu_gpr[rt]); MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm); } else { - tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], uimm << 16); + tcg_gen_movi_tl(tcg_ctx, *cpu_gpr[rt], imm << 16); MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm); } break; From 63a445cbba18bf1313ac3699b5d25462b5d529f4 Mon Sep 17 00:00:00 2001 From: Dimitris Glynos <44968893+dglynos@users.noreply.github.com> Date: Mon, 13 Dec 2021 02:40:32 +0200 Subject: [PATCH 6/6] fxsave / fxsave64 should store the floating point instruction pointer (fpip) (#1467) * fxsave / fxsave64 should store the floating point instruction pointer (fpip) - fxsave / fxsave64 happen to be used as GetPC code in exploits * unit tests for the storage of FPIP in fxsave (x86) and fxsave64 (x64) --- qemu/target-i386/fpu_helper.c | 4 +- tests/unit/Makefile | 1 + tests/unit/test_x86_fxsave_fpip.c | 118 ++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/unit/test_x86_fxsave_fpip.c diff --git a/qemu/target-i386/fpu_helper.c b/qemu/target-i386/fpu_helper.c index d4791a2a..bc210dbd 100644 --- a/qemu/target-i386/fpu_helper.c +++ b/qemu/target-i386/fpu_helper.c @@ -1127,12 +1127,12 @@ void helper_fxsave(CPUX86State *env, target_ulong ptr, int data64) cpu_stw_data(env, ptr + 4, fptag ^ 0xff); #ifdef TARGET_X86_64 if (data64) { - cpu_stq_data(env, ptr + 0x08, 0); /* rip */ + cpu_stq_data(env, ptr + 0x08, env->fpip); /* rip */ cpu_stq_data(env, ptr + 0x10, 0); /* rdp */ } else #endif { - cpu_stl_data(env, ptr + 0x08, 0); /* eip */ + cpu_stl_data(env, ptr + 0x08, (uint32_t) env->fpip); /* eip */ cpu_stl_data(env, ptr + 0x0c, 0); /* sel */ cpu_stl_data(env, ptr + 0x10, 0); /* dp */ cpu_stl_data(env, ptr + 0x14, 0); /* sel */ diff --git a/tests/unit/Makefile b/tests/unit/Makefile index c0704d34..b0775655 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -58,6 +58,7 @@ test: all ${EXECUTE_VARS} ./test_multihook ${EXECUTE_VARS} ./test_pc_change ${EXECUTE_VARS} ./test_hookcounts + ${EXECUTE_VARS} ./test_x86_fxsave_fpip echo "skipping test_tb_x86" echo "skipping test_x86_soft_paging" echo "skipping test_hang" diff --git a/tests/unit/test_x86_fxsave_fpip.c b/tests/unit/test_x86_fxsave_fpip.c new file mode 100644 index 00000000..e89d9c37 --- /dev/null +++ b/tests/unit/test_x86_fxsave_fpip.c @@ -0,0 +1,118 @@ +#include "unicorn_test.h" +#include "unicorn/unicorn.h" + +#define MEM_BASE 0x40000000 +#define MEM_SIZE 1024*1024 +#define MEM_STACK MEM_BASE + (MEM_SIZE / 2) +#define MEM_TEXT MEM_STACK + 4096 + +#define CODE_X86_NOP_OFFSET 4 +// note: fxsave was introduced in Pentium II +static uint8_t code_x86[] = { + // help testing through NOP offset [disassembly in at&t syntax] + 0x90, 0x90, 0x90, 0x90, // nop nop nop nop + // run a floating point instruction + 0xdb, 0xc9, // fcmovne %st(1), %st + // fxsave needs 512 bytes of storage space + 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // subl $512, %esp + // fxsave needs a 16-byte aligned address for storage + 0x83, 0xe4, 0xf0, // andl $0xfffffff0, %esp + // store fxsave data on the stack + 0x0f, 0xae, 0x04, 0x24, // fxsave (%esp) + // fxsave stores FPIP at an 8-byte offset, move FPIP to eax register + 0x8b, 0x44, 0x24, 0x08 // movl 0x8(%esp), %eax +}; + +#define CODE_X64_NOP_OFFSET 8 +static uint8_t code_x64[] = { + // help testing through NOP offset [disassembly in at&t] + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, // nops + // run a floating point instruction + 0xdb, 0xc9, // fcmovne %st(1), %st + // fxsave64 needs 512 bytes of storage space + 0x48, 0x81, 0xec, 0x00, 0x02, 0x00, 0x00, // subq $512, %rsp + // fxsave needs a 16-byte aligned address for storage + 0x48, 0x83, 0xe4, 0xf0, // andq 0xfffffffffffffff0, %rsp + // store fxsave64 data on the stack + 0x48, 0x0f, 0xae, 0x04, 0x24, // fxsave64 (%rsp) + // fxsave64 stores FPIP at an 8-byte offset, move FPIP to rax register + 0x48, 0x8b, 0x44, 0x24, 0x08, // movq 0x8(%rsp), %rax +}; + +static void test_x86(void **state) { + uc_err err; + uint32_t stack_top = (uint32_t) MEM_STACK; + uint32_t value; + uc_engine *uc; + + // initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc); + uc_assert_success(err); + + // map 1MB of memory for this emulation + err = uc_mem_map(uc, MEM_BASE, MEM_SIZE, UC_PROT_ALL); + uc_assert_success(err); + + err = uc_mem_write(uc, MEM_TEXT, code_x86, sizeof(code_x86)); + uc_assert_success(err); + + err = uc_reg_write(uc, UC_X86_REG_ESP, &stack_top); + uc_assert_success(err); + + err = uc_emu_start(uc, MEM_TEXT, MEM_TEXT + sizeof(code_x86), 0, 0); + uc_assert_success(err); + + err = uc_reg_read(uc, UC_X86_REG_EAX, &value); + uc_assert_success(err); + + assert_true(value == ((uint32_t) MEM_TEXT + CODE_X86_NOP_OFFSET)); + + err = uc_mem_unmap(uc, MEM_BASE, MEM_SIZE); + uc_assert_success(err); + + err = uc_close(uc); + uc_assert_success(err); +} + +static void test_x64(void **state) { + uc_err err; + uint64_t stack_top = (uint64_t) MEM_STACK; + uint64_t value; + uc_engine *uc; + + // initialize emulator in X86-32bit mode + err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc); + uc_assert_success(err); + + // map 1MB of memory for this emulation + err = uc_mem_map(uc, MEM_BASE, MEM_SIZE, UC_PROT_ALL); + uc_assert_success(err); + + err = uc_mem_write(uc, MEM_TEXT, code_x64, sizeof(code_x64)); + uc_assert_success(err); + + err = uc_reg_write(uc, UC_X86_REG_RSP, &stack_top); + uc_assert_success(err); + + err = uc_emu_start(uc, MEM_TEXT, MEM_TEXT + sizeof(code_x64), 0, 0); + uc_assert_success(err); + + err = uc_reg_read(uc, UC_X86_REG_RAX, &value); + uc_assert_success(err); + + assert_true(value == ((uint64_t) MEM_TEXT + CODE_X64_NOP_OFFSET)); + + err = uc_mem_unmap(uc, MEM_BASE, MEM_SIZE); + uc_assert_success(err); + + err = uc_close(uc); + uc_assert_success(err); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_x86), + cmocka_unit_test(test_x64), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +}