When using e9afl to instrument mruby, the program reports an illegal instruction aborted.
Invalid instructions at 0x7ffff7cbcd97
After some digging, I found that the illegal instruction is incsspq
in __longjmp
(glibc/sysdeps/x86-64/longjmp.s)]. Using gdb for debugging, I found out that %fs:[0x48]=0
(feature_1
in tcbhead_t
) in a normal program (not instrumented). However, in the instrumented program, %fs:[0x48]=0x4a1b
, which leads to the execution of incsspq
and leads to the illegal instruction problem (https://github.com/bminor/glibc/blob/ca4d3ea5130d66e66c5af14e958e99341bf20689/sysdeps/x86_64/__longjmp.S#L57-L58). According to the comments in glibc/sysdeps/x86-64/longjmp.s, this value of %fs:[0x48]
marks the shadow stack as enabled. I have no idea why this happened, can you give me some insights?
The following archive contains the normal and instrumented programs plus the input to reproduce this problem.
mruby.zip
user@c3ae4d510abb:e9afl$ ./e9afl mruby_trace
"install/e9tool" -E '".plt"' -E '".plt.got"' -O2 --option --mem-granularity=4096 -o "mruby_trace.afl" -M 'plugin("install/e9AFLPlugin.so").match()' -P 'plugin("install/e9AFLPlugin.so").patch()' --plugin="install/e9AFLPlugin.so":--counter=classic --plugin="install/e9AFLPlugin.so":-Oblock=default --plugin="/home/user/docker_share/tools/e9afl/install/e9AFLPlugin.so":-Oselect=default --plugin="install/e9AFLPlugin.so":--path='install' --option --log=false -- "mruby_trace"
-----------------------------------------------
mode = Linux ELF executable
input_binary = mruby_trace
output_binary = mruby_trace.afl
num_patched = 10015 / 10015 (100.00%)
num_patched_B1 = 8936 / 10015 (89.23%)
num_patched_B2 = 1078 / 10015 (10.76%)
num_patched_T1 = 1 / 10015 (0.01%)
num_patched_T2 = 0 / 10015 (0.00%)
num_patched_T3 = 0 / 10015 (0.00%)
num_virtual_mappings = 373
num_physical_mappings = 248 (66.49%)
num_virtual_bytes = 1527808
num_physical_bytes = 1015808 (66.49%)
input_file_size = 1738472
output_file_size = 3210016 (184.65%)
time_elapsed = 346ms
memory_used = 28468KB
pwndbg> p/x *(tcbhead_t*) $fs_base │pwndbg> p/x *(tcbhead_t*) $fs_base │·················································································································································
│$2 = { │·················································································································································
$2 = { │ tcb = 0x7ffff7c77740, │·················································································································································
tcb = 0x7ffff7c77740, │ dtv = 0x7ffff7c780a0, │·················································································································································
dtv = 0x7ffff7c780a0, │ self = 0x7ffff7c77740, │·················································································································································
self = 0x7ffff7c77740, │ multiple_threads = 0x0, │·················································································································································
multiple_threads = 0x0, │ gscope_flag = 0x0, │·················································································································································
gscope_flag = 0x0, │ sysinfo = 0x0, │·················································································································································
sysinfo = 0x0, │ stack_guard = 0x75556eb3f83c8600, │·················································································································································
stack_guard = 0x882e160064f5cc00, │ pointer_guard = 0x48fa0123fae3d9a4, │·················································································································································
pointer_guard = 0x7501990f9f69f8be, │ vgetcpu_cache = {0x0, 0x0}, │·················································································································································
vgetcpu_cache = {0x0, 0x0}, │ feature_1 = 0x4a1b, │·················································································································································
feature_1 = 0x0, │ __glibc_unused1 = 0x0, │·················································································································································
__glibc_unused1 = 0x0, │ __private_tm = {0x0, 0x0, 0x0, 0x0}, │·················································································································································
__private_tm = {0x0, 0x0, 0x0, 0x0}, │ __private_ss = 0x0, │·················································································································································
__private_ss = 0x0, │ ssp_base = 0x0, │·················································································································································
ssp_base = 0x0, │ __glibc_unused2 = {{{ │·················································································································································
__glibc_unused2 = {{{ │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }}, {{ │·················································································································································
}}, {{ │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0} │·················································································································································
i = {0x0, 0x0, 0x0, 0x0} │ }, { │·················································································································································
}, { │ i = {0x0, 0x0, 0x0, 0x0}