AFLplusplus: Remove -fsanitize-undefined-trap-on-error from UBSAN?

I am fuzzing some of postgres internals. And recntly I’ve moved from

CFLAGS=-fsanitize=address;-fsanitize=undefined;-fno-sanitize-recover=undefined
LDFLAGS=-fsanitize=address;-fsanitize=undefined

to

AFL_USE_ASAN=1
AFL_USE_UBSAN=1

and got an unexpected error while running initdb. It said Illegal instruction in the middle of initdb process…

How to reporduce

Build a modern aflpp from master. Then

$ git clone git://git.postgresql.org/git/postgresql.git -b REL_11_9
$ cd postgresql
$ CC=/usr/local/bin/afl-cc CXX=/usr/local/bin/afl-cc AFL_USE_ASAN=1 AFL_USE_UBSAN=1 ./configure --prefix=/tmp/pg --enable-tap-tests --enable-debug --enable-cassert --enable-nls --with-openssl --
$ AFL_USE_ASAN=1 AFL_USE_UBSAN=1 make
$ AFL_USE_ASAN=1 AFL_USE_UBSAN=1 make install
$ ASAN_OPTIONS=detect_leaks=0 /tmp/pg/bin/initdb -D /tmp/pg-data

You will get

The files belonging to this database system will be owned by user "nataraj".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default database encoding has accordingly been set to "SQL_ASCII".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /tmp/pg-data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default timezone ... Europe/Moscow
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... 
Illegal instruction
child process exited with exit code 132

How to gdb into it

Postgres’es initdb process is a bit tricky. Initdb creates directory tree for future database storage, and then runs postgres in single mode, and gives it an initial sql sequence that creates default db. The problem is somewhere inside postgres process, so we should run the same sequence manually. Now I just tell how to do it, if it is necessary, feel free to ask, I will explain why it is done that way.

First apply to the postgres code two patches from this archive files.tar.gz

and rebuild and reinstall postgres.

Second run expore.sh from that archive. (If you built postgres exactly with commands I’ve provided above, it will work. If you’ve changes pathes, change PGDATA and PGROOT vars inside the script)

This script will run initd, create needed data dirs, dump sql sequence into /tmp/pg/pg.bki, then properly run postgres process under gdb, so you will be able to feed it with this /tmp/pg/pg.bki

So, you run

./expore.sh

then inside gdb

b TransactionIdSetPageStatus
run --boot -x1 -X 16777216 -F -D /tmp/pg-data </tmp/pg/pg.bki

and then press n untill you see TransactionIdSetPageStatus again.

On this call it will give that Illegal instruction. You press n once again, and it will crash. I hope you can take it from that point.

It is 100% reproducible. I run it on amd64 arch on Buster Debian Linux, using clang-11 backported from unstable package.

Hope that all of this would be useful, and will help improving AFL++

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (21 by maintainers)

Commits related to this issue

Most upvoted comments

that is still from original vanilla afl. the reasons AFAIK is that execution is faster, and for fuzzing that is what you want. havent tested though if that is true.

I’ve tested it all around.

The cause of my illegall instruction problem is -fsanitize-undefined-trap-on-error option

When I build without it, but only -fsanitize=undefined -fno-sanitize-recover=all Everything works well… It fails on UBSan check with proper human readable diagnostic:

The files belonging to this database system will be owned by user "nataraj".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default database encoding has accordingly been set to "SQL_ASCII".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /tmp/pg-data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default timezone ... Europe/Moscow
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... clog.c:299:10: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:64:33: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior clog.c:299:10 in 
child process exited with exit code 1
initdb: removing data directory "/tmp/pg-data"

Why -fsanitize-undefined-trap-on-error have been ever added to AFL_USE_UBSAN options? Is it still needed there? --fno-sanitize-recover=all gives us failings when UBSan detect problems. From my point of view -fsanitize-undefined-trap-on-error gives only problems. Is there any reason it is used there?