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!