Skip to content

Commit

Permalink
Disable control flow integrity for instruction dispatching (#236)
Browse files Browse the repository at this point in the history
Return-oriented programming (ROP) manipulates the stack to compromise
control flow and execute malicious code. Recent Linux distributions such
as Ubuntu enforce control-flow enforcement protection, by generating
extra instructions. To avoid potential code bloating, passing
"-fcf-protection=none" to GCC/Clang disables endbr64 instruction
generation, resulting in a slightly shorter instruction dispatch path.  

[ original ]
$ size build/rv32emu
   text    data     bss     dec     hex filename
  94637    3920    4464  103021   1926d build/rv32emu

000000000000b2b0 <do_addi>:
    b2b0:       f3 0f 1e fa             endbr64
    b2b4:       48 83 87 a8 01 00 00    addq   $0x1,0x1a8(%rdi)
    b2bb:       01
    b2bc:       0f b6 4e 05             movzbl 0x5(%rsi),%ecx
    b2c0:       0f b6 56 04             movzbl 0x4(%rsi),%edx
    b2c4:       8b 06                   mov    (%rsi),%eax
    b2c6:       03 44 8f 58             add    0x58(%rdi,%rcx,4),%eax
    b2ca:       89 44 97 58             mov    %eax,0x58(%rdi,%rdx,4)
    b2ce:       0f b6 46 1c             movzbl 0x1c(%rsi),%eax
    b2d2:       01 87 d8 00 00 00       add    %eax,0xd8(%rdi)
    b2d8:       0f b6 46 1d             movzbl 0x1d(%rsi),%eax
    b2dc:       84 c0                   test   %al,%al
    b2de:       75 18                   jne    b2f8 <do_addi+0x48>
    b2e0:       0f b6 87 10 01 00 00    movzbl 0x110(%rdi),%eax
    b2e7:       84 c0                   test   %al,%al
    b2e9:       75 0d                   jne    b2f8 <do_addi+0x48>
    b2eb:       48 8b 76 38             mov    0x38(%rsi),%rsi
    b2ef:       ff 66 20                jmpq   *0x20(%rsi)
    b2f2:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    b2f8:       c3                      retq
    b2f9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

[ proposed ]
$ size build/rv32emu
   text    data     bss     dec     hex filename
  91845    3920    4464  100229   18785 build/rv32emu

000000000000a970 <do_addi>:
    a970:       48 83 87 a8 01 00 00    addq   $0x1,0x1a8(%rdi)
    a977:       01
    a978:       0f b6 4e 05             movzbl 0x5(%rsi),%ecx
    a97c:       0f b6 56 04             movzbl 0x4(%rsi),%edx
    a980:       8b 06                   mov    (%rsi),%eax
    a982:       03 44 8f 58             add    0x58(%rdi,%rcx,4),%eax
    a986:       89 44 97 58             mov    %eax,0x58(%rdi,%rdx,4)
    a98a:       0f b6 46 1c             movzbl 0x1c(%rsi),%eax
    a98e:       01 87 d8 00 00 00       add    %eax,0xd8(%rdi)
    a994:       0f b6 46 1d             movzbl 0x1d(%rsi),%eax
    a998:       0a 87 10 01 00 00       or     0x110(%rdi),%al
    a99e:       75 10                   jne    a9b0 <do_addi+0x40>
    a9a0:       48 8b 76 38             mov    0x38(%rsi),%rsi
    a9a4:       ff 66 20                jmpq   *0x20(%rsi)
    a9a7:       66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
    a9ae:       00 00
    a9b0:       c3                      retq
    a9b1:       66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
    a9b8:       00 00 00 00
    a9bc:       0f 1f 40 00             nopl   0x0(%rax)
  • Loading branch information
jserv authored Oct 2, 2023
1 parent 0031224 commit 79ce192
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ endif

# For tail-call elimination, we need a specific set of build flags applied.
# FIXME: On macOS + Apple Silicon, -fno-stack-protector might have a negative impact.
$(OUT)/emulate.o: CFLAGS += -fomit-frame-pointer -fno-stack-check -fno-stack-protector
$(OUT)/emulate.o: CFLAGS += $(CFLAGS_NO_CET) -fomit-frame-pointer -fno-stack-check -fno-stack-protector

# Clear the .DEFAULT_GOAL special variable, so that the following turns
# to the first target after .DEFAULT_GOAL is not set.
Expand Down
9 changes: 9 additions & 0 deletions mk/toolchain.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ else
endif
endif

CFLAGS_NO_CET :=
processor := $(shell uname -m)
ifeq ($(processor),$(filter $(processor),i386 x86_64))
# GCC and Clang can generate support code for Intel's Control-flow
# Enforcement Technology (CET) through this compiler flag:
# -fcf-protection=[full]
CFLAGS_NO_CET := -fcf-protection=none
endif

# As of Xcode 15, linker warnings are emitted if duplicate '-l' options are
# present. Until such linkopts can be deduped by the build system, we disable
# these warnings.
Expand Down
2 changes: 1 addition & 1 deletion src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ enum {
};

#if RV32_HAS(GDBSTUB)
#define RVOP_NO_NEXT(ir) (ir->tailcall || rv->debug_mode)
#define RVOP_NO_NEXT(ir) (ir->tailcall | rv->debug_mode)
#else
#define RVOP_NO_NEXT(ir) (ir->tailcall)
#endif
Expand Down

1 comment on commit 79ce192

@jserv
Copy link
Contributor Author

@jserv jserv commented on 79ce192 Oct 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: 79ce192 Previous: ae2de71 Ratio
Dhrystone 1136.25 Average DMIPS over 10 runs 1125.88 Average DMIPS over 10 runs 0.99
Coremark 988.202 Average iterations/sec over 10 runs 966.574 Average iterations/sec over 10 runs 0.98

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.