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
2
set environment LD_PRELOAD=./printf.so
set args -q

Amazing! ctarget can be normally run on Ubuntu 22.04 now!