Fix CS:APP Attack Lab Segmentation Fault on Newest Ubuntu 22.04
In the 3rd Lab of CS:APP: Attack Lab, the
distributed binary ctarget is too old and it cannot
normally run on today's Ubuntu 22.04. I tried to analyze the problem and
raise a resolution for that.
Related stack overflow question.
Description
When running ./ctarget -q on my Ubuntu 22.04, it skips
the input and raises a Segmentation Fault. Using gdb, I found that it is
due to an instruction in __vfprintf_internal of my
glibc, namely movaps %xmm1, 0x10(%rsp). This
instruction needs its memory operand 0x10(%rsp)
corresponding an address divisible by 16. I guess that due to the
compiling of ctarget is on a old convention, where the size
of function frame is not strictly required to be a multiple of 16. I
tried to manually modify the low bits of %rsp through gdb,
and it eliminates the SIGSEGV, confirming my guessing.
Fix the problem
In the Stack
overflow reply, I try to add an interface to make
printf family "adaptive" to the alignment of
%rsp. But it does not work quite well throughout the
experiment. Instead, in this blog, I will use a naive self-made version
printf family and LD_PRELOAD to fix that.
Get self-made
printf.so
First of all, we can find a naive printf implementation (For me, I
use the programming homework in NJU
PA). Then we can compile it to be a shared library(suppose the
source file is named printf.c):
1 | $ gcc -shared -fPIC -o printf.so printf.c |
Notice that we shall provide interface __printf_chk and
__sprintf_chk.
I provide a compiled shared library here: printf.so.
Use
the LD_PRELOAD to substitute the default glibc shared
library
Put printf.so in the same directory of
ctarget, then use command
1 | $ LD_PRELOAD=./printf.so ./ctarget -q |
And it works!
Also, to set LD_PRELOAD in gdb, we can use
1 | set environment LD_PRELOAD=./printf.so |
Amazing! ctarget can be normally run on Ubuntu 22.04
now!