From 59ed62fb2fdd8e7bcb2215cfe0156823f2400956 Mon Sep 17 00:00:00 2001 From: Florent Bordignon Date: Sun, 11 Apr 2021 17:45:30 +0200 Subject: [PATCH 1/4] Fix memfd.diff not applied on Ubuntu 20.04 Most of the modifications in build_qemu.diff are due to the fact that the diff algorithm that I used to generate it is different from the algorithm used by the previous contributor. (I used git diff --diff-algorithm=histogram) Only the part with apply_patch changes. --- patches/build_qemu.diff | 47 ++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/patches/build_qemu.diff b/patches/build_qemu.diff index 65e324d..9813fb2 100644 --- a/patches/build_qemu.diff +++ b/patches/build_qemu.diff @@ -1,5 +1,5 @@ ---- qemu_mode/build_qemu_support.sh 2019-01-26 15:02:56.276349827 -0700 -+++ /qemu_mode/build_qemu_support.sh 2019-01-26 15:48:59.953197930 -0700 +--- qemu_mode/build_qemu_support.sh ++++ qemu_mode/build_qemu_support.sh @@ -22,6 +22,10 @@ # will be written to ../afl-qemu-trace. # @@ -11,7 +11,7 @@ VERSION="2.10.0" QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz" -@@ -115,15 +119,11 @@ +@@ -115,15 +119,11 @@ echo "[*] Uncompressing archive (this will take a while)..." rm -rf "qemu-${VERSION}" || exit 1 tar xf "$ARCHIVE" || exit 1 @@ -28,11 +28,20 @@ cd qemu-$VERSION || exit 1 echo "[*] Applying patches..." -@@ -132,26 +132,40 @@ +@@ -132,26 +132,49 @@ patch -p1 <../patches/elfload.diff || exit 1 patch -p1 <../patches/cpu-exec.diff || exit 1 patch -p1 <../patches/syscall.diff || exit 1 -+if [ "`lsb_release -a 2>/dev/null | grep Release | awk '{print $2}'`" = 18.04 ]; then ++apply_patch=0 ++if [ `lsb_release -a 2>/dev/null | grep 'Distributor ID' | awk '{print $3}'` = Ubuntu ]; then ++ if [ `lsb_release -a 2>/dev/null | grep 'Release' | awk '{print $2}' | tr -d .` -ge 1804 ]; then ++ apply_patch=1 ++ fi ++else ++ apply_patch=1 ++fi ++ ++if [ $apply_patch -eq 1 ]; then + patch -p1 <../patches/memfd.diff +fi + @@ -41,35 +50,35 @@ -# --enable-pie seems to give a couple of exec's a second performance -# improvement, much to my surprise. Not sure how universal this is.. +CPU_TARGETS=$@ -+ -+for CPU_TARGET in $CPU_TARGETS; do -+ -+ # --enable-pie seems to give a couple of exec's a second performance -+ # improvement, much to my surprise. Not sure how universal this is.. -CFLAGS="-O3 -ggdb" ./configure --disable-system \ - --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \ - --target-list="${CPU_TARGET}-linux-user" --enable-pie --enable-kvm || exit 1 -+ CFLAGS="-O3 -ggdb" ./configure --disable-system --python=`which python2` \ -+ --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \ -+ --target-list="${CPU_TARGET}-linux-user" --enable-pie --enable-kvm || exit 1 ++for CPU_TARGET in $CPU_TARGETS; do -echo "[+] Configuration complete." -+ echo "[+] Configuration complete." ++ # --enable-pie seems to give a couple of exec's a second performance ++ # improvement, much to my surprise. Not sure how universal this is.. -echo "[*] Attempting to build QEMU (fingers crossed!)..." -+ echo "[*] Attempting to build QEMU (fingers crossed!)..." ++ CFLAGS="-O3 -ggdb" ./configure --disable-system --python=`which python2` \ ++ --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \ ++ --target-list="${CPU_TARGET}-linux-user" --enable-pie --enable-kvm || exit 1 -make || exit 1 -+ make || exit 1 ++ echo "[+] Configuration complete." -echo "[+] Build process successful!" -+ echo "[+] Build process successful!" ++ echo "[*] Attempting to build QEMU (fingers crossed!)..." -echo "[*] Copying binary..." -+ echo "[*] Copying binary..." ++ make || exit 1 -cp -f "${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 ++ echo "[+] Build process successful!" ++ ++ echo "[*] Copying binary..." ++ + cp -f "${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 + + mkdir -p ../../tracers/$CPU_TARGET @@ -80,7 +89,7 @@ cd .. ls -l ../afl-qemu-trace || exit 1 -@@ -166,29 +180,29 @@ +@@ -166,29 +189,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then make >/dev/null || exit 1 From a3289a0d6036e0471d241f2de7a2b376b35147f7 Mon Sep 17 00:00:00 2001 From: Florent Bordignon Date: Sun, 11 Apr 2021 18:45:17 +0200 Subject: [PATCH 2/4] Fix static declaration of 'gettid' follows non-static declaration --- patches/build_qemu.diff | 22 +++++++++++++------ patches/gettid.diff | 47 +++++++++++++++++++++++++++++++++++++++++ setup.py | 8 +++---- 3 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 patches/gettid.diff diff --git a/patches/build_qemu.diff b/patches/build_qemu.diff index 9813fb2..1e49475 100644 --- a/patches/build_qemu.diff +++ b/patches/build_qemu.diff @@ -28,22 +28,32 @@ cd qemu-$VERSION || exit 1 echo "[*] Applying patches..." -@@ -132,26 +132,49 @@ patch -p1 <../patches/elfload.diff || exit 1 +@@ -132,26 +132,59 @@ patch -p1 <../patches/elfload.diff || exit 1 patch -p1 <../patches/cpu-exec.diff || exit 1 patch -p1 <../patches/syscall.diff || exit 1 -+apply_patch=0 ++# some patches are needed for Ubuntu 20.04 but not for Ubuntu 18.04 ++# (I have not tested other distributions) ++apply_patch_18_04=0 ++apply_patch_above_18_04=0 +if [ `lsb_release -a 2>/dev/null | grep 'Distributor ID' | awk '{print $3}'` = Ubuntu ]; then + if [ `lsb_release -a 2>/dev/null | grep 'Release' | awk '{print $2}' | tr -d .` -ge 1804 ]; then -+ apply_patch=1 ++ apply_patch_18_04=1 ++ fi ++ if [ `lsb_release -a 2>/dev/null | grep 'Release' | awk '{print $2}' | tr -d .` -gt 1804 ]; then ++ apply_patch_above_18_04=1 + fi +else -+ apply_patch=1 ++ apply_patch_18_04=1 ++ apply_patch_above_18_04=1 +fi + -+if [ $apply_patch -eq 1 ]; then ++if [ $apply_patch_18_04 -eq 1 ]; then + patch -p1 <../patches/memfd.diff +fi ++if [ $apply_patch_above_18_04 -eq 1 ]; then ++ patch -p1 <../patches/gettid.diff ++fi + echo "[+] Patching done." @@ -89,7 +99,7 @@ cd .. ls -l ../afl-qemu-trace || exit 1 -@@ -166,29 +189,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then +@@ -166,29 +199,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then make >/dev/null || exit 1 diff --git a/patches/gettid.diff b/patches/gettid.diff new file mode 100644 index 0000000..f059f65 --- /dev/null +++ b/patches/gettid.diff @@ -0,0 +1,47 @@ +--- qemu-2.10.0/linux-user/syscall.c ++++ qemu-2.10.0/linux-user/syscall.c +@@ -259,11 +259,12 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ + #endif + + #ifdef __NR_gettid ++#define __NR_sys_gettid __NR_gettid +-_syscall0(int, gettid) ++_syscall0(int, sys_gettid) + #else + /* This is a replacement for the host gettid() and must return a host + errno. */ +-static int gettid(void) { ++static int sys_gettid(void) { + return -ENOSYS; + } + #endif +@@ -6222,7 +6222,7 @@ static void *clone_func(void *arg) + cpu = ENV_GET_CPU(env); + thread_cpu = cpu; + ts = (TaskState *)cpu->opaque; +- info->tid = gettid(); ++ info->tid = sys_gettid(); + task_settid(ts); + if (info->child_tidptr) + put_user_u32(info->tid, info->child_tidptr); +@@ -6366,9 +6366,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, + mapping. We can't repeat the spinlock hack used above because + the child process gets its own copy of the lock. */ + if (flags & CLONE_CHILD_SETTID) +- put_user_u32(gettid(), child_tidptr); ++ put_user_u32(sys_gettid(), child_tidptr); + if (flags & CLONE_PARENT_SETTID) +- put_user_u32(gettid(), parent_tidptr); ++ put_user_u32(sys_gettid(), parent_tidptr); + ts = (TaskState *)cpu->opaque; + if (flags & CLONE_SETTLS) + cpu_set_tls (env, newtls); +@@ -11405,7 +11405,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + break; + #endif + case TARGET_NR_gettid: +- ret = get_errno(gettid()); ++ ret = get_errno(sys_gettid()); + break; + #ifdef TARGET_NR_readahead + case TARGET_NR_readahead: diff --git a/setup.py b/setup.py index 444a667..a332f37 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ AFL_CGC_INSTALL_PATH = os.path.join("bin", "afl-cgc") AFL_MULTI_CGC_INSTALL_PATH = os.path.join("bin", "afl-multi-cgc") SUPPORTED_ARCHES = ["aarch64", "x86_64", "i386", "arm", "ppc", "ppc64", "mips", "mipsel", "mips64"] -QEMU_PATCH = "patches/memfd.diff" +QEMU_PATCHES = ["patches/memfd.diff", "patches/gettid.diff"] MULTIARCH_LIBRARY_PATH = os.path.join("bin", "fuzzer-libs") AFL_QEMU_MODE_PATCH = AFL_UNIX_INSTALL_PATH+"/qemu_mode/patches/" AFL_UNIX_FUZZ = os.path.join(AFL_UNIX_INSTALL_PATH) @@ -35,9 +35,9 @@ def _setup_other_arch(): if subprocess.call(['cp',AFL_UNIX_GEN, AFL_UNIX_INSTALL_PATH]) != 0: raise LibError("Build file doesn't exist") - # patch for qemu to work with ubuntu 18.04 and above - if subprocess.check_call(['cp',QEMU_PATCH,AFL_QEMU_MODE_PATCH]) != 0: - raise LibError('Patch to work Qemu with Ubuntu 18 not found') + # patches for QEMU to work with ubuntu 18.04 and above + if subprocess.check_call(['cp'] + QEMU_PATCHES + [AFL_QEMU_MODE_PATCH]) != 0: + raise LibError('Patches to make QEMU work with Ubuntu 18.04 and above not found') if subprocess.check_call(['./build.sh'] + SUPPORTED_ARCHES, cwd=AFL_UNIX_INSTALL_PATH) != 0: raise LibError("Unable to build afl-other-arch") From abeceb4abbf4afc37f93a6019b4d450bc51b3341 Mon Sep 17 00:00:00 2001 From: Florent Bordignon Date: Sun, 11 Apr 2021 19:03:38 +0200 Subject: [PATCH 3/4] Fix SIOCGSTAMP undeclared --- patches/build_qemu.diff | 13 +++++++------ patches/syscall_sockios.diff | 10 ++++++++++ setup.py | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 patches/syscall_sockios.diff diff --git a/patches/build_qemu.diff b/patches/build_qemu.diff index 1e49475..fa650b7 100644 --- a/patches/build_qemu.diff +++ b/patches/build_qemu.diff @@ -28,31 +28,32 @@ cd qemu-$VERSION || exit 1 echo "[*] Applying patches..." -@@ -132,26 +132,59 @@ patch -p1 <../patches/elfload.diff || exit 1 +@@ -132,26 +132,60 @@ patch -p1 <../patches/elfload.diff || exit 1 patch -p1 <../patches/cpu-exec.diff || exit 1 patch -p1 <../patches/syscall.diff || exit 1 +# some patches are needed for Ubuntu 20.04 but not for Ubuntu 18.04 +# (I have not tested other distributions) +apply_patch_18_04=0 -+apply_patch_above_18_04=0 ++apply_patches_above_18_04=0 +if [ `lsb_release -a 2>/dev/null | grep 'Distributor ID' | awk '{print $3}'` = Ubuntu ]; then + if [ `lsb_release -a 2>/dev/null | grep 'Release' | awk '{print $2}' | tr -d .` -ge 1804 ]; then + apply_patch_18_04=1 + fi + if [ `lsb_release -a 2>/dev/null | grep 'Release' | awk '{print $2}' | tr -d .` -gt 1804 ]; then -+ apply_patch_above_18_04=1 ++ apply_patches_above_18_04=1 + fi +else + apply_patch_18_04=1 -+ apply_patch_above_18_04=1 ++ apply_patches_above_18_04=1 +fi + +if [ $apply_patch_18_04 -eq 1 ]; then + patch -p1 <../patches/memfd.diff +fi -+if [ $apply_patch_above_18_04 -eq 1 ]; then ++if [ $apply_patches_above_18_04 -eq 1 ]; then + patch -p1 <../patches/gettid.diff ++ patch -p1 <../patches/syscall_sockios.diff +fi + echo "[+] Patching done." @@ -99,7 +100,7 @@ cd .. ls -l ../afl-qemu-trace || exit 1 -@@ -166,29 +199,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then +@@ -166,29 +200,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then make >/dev/null || exit 1 diff --git a/patches/syscall_sockios.diff b/patches/syscall_sockios.diff new file mode 100644 index 0000000..886cd78 --- /dev/null +++ b/patches/syscall_sockios.diff @@ -0,0 +1,10 @@ +--- qemu-2.10.0/linux-user/syscall.c ++++ qemu-2.10.0/linux-user/syscall.c +@@ -41,6 +41,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, + size_t stack_size, int flags, void *arg, ...); + #endif + #include ++#include + #include + #include + #include diff --git a/setup.py b/setup.py index a332f37..8050a95 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ AFL_CGC_INSTALL_PATH = os.path.join("bin", "afl-cgc") AFL_MULTI_CGC_INSTALL_PATH = os.path.join("bin", "afl-multi-cgc") SUPPORTED_ARCHES = ["aarch64", "x86_64", "i386", "arm", "ppc", "ppc64", "mips", "mipsel", "mips64"] -QEMU_PATCHES = ["patches/memfd.diff", "patches/gettid.diff"] +QEMU_PATCHES = ["patches/memfd.diff", "patches/gettid.diff", "patches/syscall_sockios.diff"] MULTIARCH_LIBRARY_PATH = os.path.join("bin", "fuzzer-libs") AFL_QEMU_MODE_PATCH = AFL_UNIX_INSTALL_PATH+"/qemu_mode/patches/" AFL_UNIX_FUZZ = os.path.join(AFL_UNIX_INSTALL_PATH) From a0f7f50f9881cbcac83e8eed3478e478a3785516 Mon Sep 17 00:00:00 2001 From: Florent Bordignon Date: Sun, 11 Apr 2021 19:14:15 +0200 Subject: [PATCH 4/4] Fix undefined reference to `stime' --- patches/build_qemu.diff | 5 +++-- patches/stime.diff | 17 +++++++++++++++++ setup.py | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 patches/stime.diff diff --git a/patches/build_qemu.diff b/patches/build_qemu.diff index fa650b7..d311661 100644 --- a/patches/build_qemu.diff +++ b/patches/build_qemu.diff @@ -28,7 +28,7 @@ cd qemu-$VERSION || exit 1 echo "[*] Applying patches..." -@@ -132,26 +132,60 @@ patch -p1 <../patches/elfload.diff || exit 1 +@@ -132,26 +132,61 @@ patch -p1 <../patches/elfload.diff || exit 1 patch -p1 <../patches/cpu-exec.diff || exit 1 patch -p1 <../patches/syscall.diff || exit 1 @@ -54,6 +54,7 @@ +if [ $apply_patches_above_18_04 -eq 1 ]; then + patch -p1 <../patches/gettid.diff + patch -p1 <../patches/syscall_sockios.diff ++ patch -p1 <../patches/stime.diff +fi + echo "[+] Patching done." @@ -100,7 +101,7 @@ cd .. ls -l ../afl-qemu-trace || exit 1 -@@ -166,29 +200,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then +@@ -166,29 +201,29 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then make >/dev/null || exit 1 diff --git a/patches/stime.diff b/patches/stime.diff new file mode 100644 index 0000000..6711e8d --- /dev/null +++ b/patches/stime.diff @@ -0,0 +1,17 @@ +--- qemu-2.10.0/linux-user/syscall.c ++++ qemu-2.10.0/linux-user/syscall.c +@@ -8157,10 +8157,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, + #ifdef TARGET_NR_stime /* not on alpha */ + case TARGET_NR_stime: + { +- time_t host_time; +- if (get_user_sal(host_time, arg1)) ++ struct timespec ts; ++ ts.tv_nsec = 0; ++ if (get_user_sal(ts.tv_sec, arg1)) + goto efault; +- ret = get_errno(stime(&host_time)); ++ ret = get_errno(clock_settime(CLOCK_REALTIME, &ts)); + } + break; + #endif diff --git a/setup.py b/setup.py index 8050a95..9b9189f 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ AFL_CGC_INSTALL_PATH = os.path.join("bin", "afl-cgc") AFL_MULTI_CGC_INSTALL_PATH = os.path.join("bin", "afl-multi-cgc") SUPPORTED_ARCHES = ["aarch64", "x86_64", "i386", "arm", "ppc", "ppc64", "mips", "mipsel", "mips64"] -QEMU_PATCHES = ["patches/memfd.diff", "patches/gettid.diff", "patches/syscall_sockios.diff"] +QEMU_PATCHES = ["patches/memfd.diff", "patches/gettid.diff", "patches/syscall_sockios.diff", "patches/stime.diff"] MULTIARCH_LIBRARY_PATH = os.path.join("bin", "fuzzer-libs") AFL_QEMU_MODE_PATCH = AFL_UNIX_INSTALL_PATH+"/qemu_mode/patches/" AFL_UNIX_FUZZ = os.path.join(AFL_UNIX_INSTALL_PATH)