Re: [PATCH 1/2] Wrapper for Syzkaller reproducers

19 views
Skip to first unread message

Dmitry Vyukov

unread,
Nov 7, 2019, 10:43:45 AM11/7/19
to Richard Palethorpe, l...@lists.linux.it, automate...@yoctoproject.org, syzkaller
On Thu, Nov 7, 2019 at 4:35 PM Richard Palethorpe <rpale...@suse.com> wrote:
>
> Allows one to run the Syzkaller reproducers as part of the LTP.
>
> Signed-off-by: Richard Palethorpe <rpale...@suse.com>
> ---
> .gitmodules | 5 +
> configure.ac | 11 ++
> include/mk/features.mk.default | 2 +
> include/mk/features.mk.in | 2 +
> runtest/.gitignore | 1 +
> testcases/kernel/Makefile | 1 +
> testcases/kernel/syzkaller-repros/.gitignore | 1 +
> testcases/kernel/syzkaller-repros/Makefile | 100 ++++++++++++++
> testcases/kernel/syzkaller-repros/README.md | 45 +++++++
> testcases/kernel/syzkaller-repros/syzwrap.c | 133 +++++++++++++++++++
> 10 files changed, 301 insertions(+)
> create mode 100644 runtest/.gitignore
> create mode 100644 testcases/kernel/syzkaller-repros/.gitignore
> create mode 100644 testcases/kernel/syzkaller-repros/Makefile
> create mode 100644 testcases/kernel/syzkaller-repros/README.md
> create mode 100644 testcases/kernel/syzkaller-repros/syzwrap.c
>
> diff --git a/.gitmodules b/.gitmodules
> index 1c9e9c38a..6a2d31f51 100644
> --- a/.gitmodules
> +++ b/.gitmodules
> @@ -1,3 +1,8 @@
> [submodule "testcases/kernel/mce-test"]
> path = testcases/kernel/mce-test
> url = git://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/mce-test.git
> +[submodule "testcases/linux-arts"]
> + path = testcases/linux-arts
> + url = https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-arts.git
> + shallow = true
> + ignore = all
> diff --git a/configure.ac b/configure.ac
> index 3785dff63..ec4cae483 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -184,6 +184,17 @@ else
> AC_SUBST([WITH_OPEN_POSIX_TESTSUITE],["no"])
> fi
>
> +AC_ARG_WITH([syzkaller-repros],
> + [AC_HELP_STRING([--with-syzkaller-repros],
> + [compile and install Syzkaller reproducers (default=no)])],
> + [with_syzkaller_repros=$withval]
> +)
> +if test "x$with_syzkaller_repros" = xyes; then
> + AC_SUBST([WITH_SYZKALLER_REPROS],["yes"])
> +else
> + AC_SUBST([WITH_SYZKALLER_REPROS],["no"])
> +fi
> +
> # testcases/realtime requires bash and python.
> if test "x$with_bash" = xyes && test "x$with_python" = xyes; then
> AC_ARG_WITH([realtime-testsuite],
> diff --git a/include/mk/features.mk.default b/include/mk/features.mk.default
> index 3a6cc5176..71fb48c60 100644
> --- a/include/mk/features.mk.default
> +++ b/include/mk/features.mk.default
> @@ -47,3 +47,5 @@ WITH_REALTIME_TESTSUITE := no
> else
> WITH_REALTIME_TESTSUITE := no
> endif
> +
> +WITH_SYZKALLER_REPROS := no
> diff --git a/include/mk/features.mk.in b/include/mk/features.mk.in
> index 8e561b738..3ab7f4721 100644
> --- a/include/mk/features.mk.in
> +++ b/include/mk/features.mk.in
> @@ -47,3 +47,5 @@ WITH_REALTIME_TESTSUITE := no
> else
> WITH_REALTIME_TESTSUITE := @WITH_REALTIME_TESTSUITE@
> endif
> +
> +WITH_SYZKALLER_REPROS := @WITH_SYZKALLER_REPROS@
> diff --git a/runtest/.gitignore b/runtest/.gitignore
> new file mode 100644
> index 000000000..2ae05bfac
> --- /dev/null
> +++ b/runtest/.gitignore
> @@ -0,0 +1 @@
> +syzkaller*
> diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
> index 3319b3163..0150cfb4f 100644
> --- a/testcases/kernel/Makefile
> +++ b/testcases/kernel/Makefile
> @@ -53,6 +53,7 @@ SUBDIRS += connectors \
> sched \
> security \
> sound \
> + syzkaller-repros \
> tracing \
> uevents \
>
> diff --git a/testcases/kernel/syzkaller-repros/.gitignore b/testcases/kernel/syzkaller-repros/.gitignore
> new file mode 100644
> index 000000000..dbda1c71f
> --- /dev/null
> +++ b/testcases/kernel/syzkaller-repros/.gitignore
> @@ -0,0 +1 @@
> +syzwrap
> diff --git a/testcases/kernel/syzkaller-repros/Makefile b/testcases/kernel/syzkaller-repros/Makefile
> new file mode 100644
> index 000000000..d40d61ac1
> --- /dev/null
> +++ b/testcases/kernel/syzkaller-repros/Makefile
> @@ -0,0 +1,100 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2019 Linux Test Project
> +
> +top_srcdir ?= ../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +CFLAGS += -D_GNU_SOURCE
> +
> +ifeq ($(WITH_SYZKALLER_REPROS),yes)
> +
> +# The number of reproducers in each runtest file
> +SYZKALLER_RUNFILES_SIZE ?= 100
> +
> +# Extra arguments to pass to syzwrap. Uncomment the below to add some
> +# sandboxing.
> +# SYZWRAP_ARGS ?= -s
> +
> +# Location where reproducers are installed
> +SYZKALLER_INSTALL_DIR ?= $(abspath $(DESTDIR)/$(prefix)/testcases/bin)
> +
> +# If the reproducers directory is missing then we automatically clone the repo.
> +# We then have to call make recursively to revaluate the targets
> +SYZKALLER_REPROS_DIR ?= $(abs_top_srcdir)/testcases/linux-arts/syzkaller-repros/linux
> +$(SYZKALLER_REPROS_DIR):
> + git submodule update --init $(abs_top_srcdir)/testcases/linux-arts
> + $(MAKE) syzkaller_runfiles
> +
> +SYZKALLER_REPROS_SRCS = $(wildcard $(SYZKALLER_REPROS_DIR)/*.c)
> +
> +# Some useful compiler flags for the LTP will cause problems with the
> +# syzkaller repros so the repros have seperate flags
> +SYZKALLER_CFLAGS ?= -pthread
> +SYZKALLER_REPROS = $(subst $(abs_top_srcdir),$(abs_top_builddir),$(SYZKALLER_REPROS_SRCS:.c=))
> +$(SYZKALLER_REPROS): %: %.c
> + -@if grep -q "__NR_mmap2" $^; then \
> + M32="-m32"; \
> + fi; \
> + $(CC) $(SYZKALLER_CFLAGS) $$M32 $(SYZKALLER_LDFLAGS) $^ -o $@; \
> + echo $(CC) $(SYZKALLER_CFLAGS) $$M32 $(SYZKALLER_LDFLAGS) $^ -o $@;
> +
> +# Generate the names of the runtest files. This uses Shell arithmetic to
> +# calculate how many runtest files there will be.
> +define SYZKALLER_RUNFILES !=
> + n=$(words $(SYZKALLER_REPROS));
> + m=$(SYZKALLER_RUNFILES_SIZE);
> + i=$$(( $$n / $$m + ($$n % $$m > 0) ));
> + while test $$i -gt 0;
> + do
> + echo $(top_srcdir)/runtest/syzkaller$$i;
> + i=$$(($$i - 1));
> + done
> +endef
> +
> +# Get the index part of a runtest files name
> +syz_n = $(subst $(top_srcdir)/runtest/syzkaller,,$(1))
> +syz_m = $(SYZKALLER_RUNFILES_SIZE)
> +# Gives the index of the first reproducer in a runtest file
> +syz_i = $(shell echo $$((($(call syz_n,$(1)) - 1) * $(2) + 1)))
> +# Gives the index of the last reproducer in a runtest file
> +syz_j = $(shell echo $$(( $(call syz_i,$(1),$(2)) + $(2) - 1 )))
> +# Gvien a runtest file name, get the reproducers it should contain
> +syz_wordlist = $(wordlist $(call syz_i,$(1),$(syz_m)),$(call syz_j,$(1),$(syz_m)),$(SYZKALLER_REPROS))
> +
> +define syz_runfile_line
> +$(notdir $(exe)) syzwrap $(SYZWRAP_ARGS) -d $(SYZKALLER_INSTALL_DIR) -n $(notdir $(exe))
> +
> +endef
> +
> +# Generate the runtest files based on the reproducer names and batch size.
> +$(SYZKALLER_RUNFILES): $(SYZKALLER_REPROS)
> + @echo "Writing $@"
> + $(file >$@)
> + $(foreach exe,$(call syz_wordlist,$@),$(file >>$@,$(syz_runfile_line)))
> +
> +.PHONY: syzkaller_runfiles
> +syzkaller_runfiles: $(SYZKALLER_RUNFILES) | $(SYZKALLER_REPROS_DIR)
> +
> +all: $(SYZKALLER_RUNFILES) | $(SYZKALLER_REPROS_DIR)
> +
> +# There are too many reproducers to pass all at once to rm, so we just pass
> +# one at a time
> +syzkaller_clean:
> + $(foreach f, $(SYZKALLER_REPROS), $(RM) $(f))
> +CLEAN_DEPS += syzkaller_clean
> +CLEAN_TARGETS += $(SYZKALLER_RUNFILES)
> +
> +INSTALL_MODE ?= 0775
> +
> +# For some reason part of the path is missing if we just try to install these
> +# by adding them to INSTALL_FILES
> +SYZKALLER_REPROS_INSTALLED := $(subst $(SYZKALLER_REPROS_DIR),$(SYZKALLER_INSTALL_DIR),$(SYZKALLER_REPROS))
> +$(SYZKALLER_REPROS_INSTALLED): $(SYZKALLER_INSTALL_DIR)/%: $(SYZKALLER_REPROS_DIR)/%
> + install -m $(INSTALL_MODE) -T $< $@
> +
> +install: $(SYZKALLER_REPROS_INSTALLED)
> +
> +endif
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syzkaller-repros/README.md b/testcases/kernel/syzkaller-repros/README.md
> new file mode 100644
> index 000000000..2c88efd01
> --- /dev/null
> +++ b/testcases/kernel/syzkaller-repros/README.md
> @@ -0,0 +1,45 @@
> +# LTP wrapper for Syzkaller reproducers
> +
> +This allows you to run the autogenerated C bug reproducers from the Syzkaller
> +fuzzer within the LTP framework. Meaning that you may use an existing test
> +runner compatible with the LTP (with some constraints, see below).
> +
> +## Instructions
> +
> +1. Run `ltp/configure` with `--with-syzkaller-repros`.
> +2. Build and install the LTP as normal.
> +3. Run one or more of syzkallerN runtest files where N is a number.
> +
> +Make will automatically download the reproducers into `testcases/linux-arts`
> +using git-submodule if necessary.
> +
> +By default each runtest file contains 100 reproducers. You may change this by
> +overriding `SYZKALLER_RUNFILES_SIZE`.
> +
> +Extra parameters can be sent to syzwrap using `SYZWRAP_ARGS`. See `syzwrap
> +-h`.
> +
> +## Kernel Requirements
> +
> +It is strongly recommended that you use KASAN and other debugging kernel
> +features. See the Syzkaller documentation for the configuration you should
> +use.
> +
> +## Test Runner Requirements
> +
> +Unlike most LTP tests these reproducers can leave your system in a broken
> +state even if no bug is triggered.
> +
> +You will need to:
> +
> +A) Reboot the SUT
> +B) Reset at least the root filesystem to a known good state
> +
> +Every time syzwrap fails.
> +
> +If syzwrap fails with TBROK or fails to run at all, then you probably need to
> +reset the system and rerun that test. If a test fails with TFAIL, you may also
> +want to run it once again with a clean state.
> +
> +It might be the case that some reproducers write to random devices or do other
> +things which can effect the outside world.
> diff --git a/testcases/kernel/syzkaller-repros/syzwrap.c b/testcases/kernel/syzkaller-repros/syzwrap.c
> new file mode 100644
> index 000000000..9f5d16078
> --- /dev/null
> +++ b/testcases/kernel/syzkaller-repros/syzwrap.c
> @@ -0,0 +1,133 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2019 Richard Palethorpe <rpale...@suse.com>
> + *
> + * Run a single reproducer generated by the Syzkaller fuzzer.
> + */
> +
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <sys/prctl.h>
> +#include <sched.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <pwd.h>
> +
> +#include "tst_test.h"
> +#include "tst_taint.h"
> +#include "tst_safe_stdio.h"
> +
> +#define SANDBOX_HELP "\n"\
> + "-s\t Add some sandboxing around the reproducer. This will prevent some\n"\
> + "\t reproducers from creating network devices and thus prevent them from\n"\
> + "\t working. However it will also prevent some reproducers from trashing\n"\
> + "\t the system using root privileges. Note that you may generate the\n"\
> + "\t reproducers with various types of sandboxing built in using\n"\
> + "\t syz-reprolist"
> +
> +static char *dir;
> +static char *name;
> +static char *path;
> +
> +static char *sandbox;
> +
> +static struct tst_option options[] = {
> + {"d:", &dir, "\n-d PATH\t Mandatory directory containing reproducers"},
> + {"n:", &name, "-n NAME\t Mandatory executable name of reproducer"},
> + {"s", &sandbox, SANDBOX_HELP},
> + {NULL, NULL, NULL}
> +};
> +
> +static void become_nobody(void)
> +{
> + struct passwd *pw;
> + int gid, uid;
> +
> + setgroups(0, NULL);
> +
> + pw = getpwnam("nobody");
> + if (pw) {
> + gid = pw->pw_gid;
> + uid = pw->pw_uid;
> + } else {
> + gid = 65534;
> + uid = 65534;
> + }
> +
> + SAFE_SETREGID(gid, gid);
> + SAFE_SETREUID(uid, uid);
> +}
> +
> +static void setup(void)
> +{
> + tst_taint_init(TST_TAINT_W | TST_TAINT_D | TST_TAINT_L);
> +
> + if (!dir)
> + tst_brk(TBROK, "No reproducer directory specified");
> +
> + if (!name)
> + tst_brk(TBROK, "No reproducer name specified");
> +
> + tst_res(TINFO, "https://syzkaller.appspot.com/bug?id=%s", name);
> +
> + SAFE_ASPRINTF(&path, "%s/%s", dir, name);
> + tst_res(TINFO, "%s", path);
> +}
> +
> +static void run(void)
> +{
> + unsigned int backoff = 100;
> + int rem, status, sent_kill = 0;
> + float exec_time_start = (float)tst_timeout_remaining();
> + int pid;
> +
> + if (sandbox)
> + SAFE_UNSHARE(CLONE_NEWPID);
> +
> + pid = SAFE_FORK();
> + if (!pid) {
> + if (sandbox) {
> + SAFE_UNSHARE(CLONE_NEWNET);
> + become_nobody();
> + }
> +
> + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
> + tst_res(TWARN | TERRNO,
> + "Failed to set dumpable; won't be able to open /proc/self/*");
> + }
> +
> + execl(path, name, NULL);
> + tst_brk(TBROK | TERRNO, "Failed to exec reproducer");
> + }
> +
> + while (!waitpid(pid, &status, WNOHANG)) {
> + rem = tst_timeout_remaining();
> +
> + if (!sent_kill && rem / exec_time_start < 0.5) {
> + tst_res(TINFO, "Timeout; killing reproducer");
> +
> + TEST(kill(pid, SIGKILL));
> + if (TST_RET == -1)
> + tst_res(TWARN | TTERRNO, "kill() failed");
> + else
> + sent_kill = 1;
> + }
> +
> + usleep(backoff);
> + backoff = MIN(2 * backoff, 1000000);
> + }
> +
> + if (tst_taint_check()) {
> + tst_res(TFAIL, "Kernel is tainted");
> + } else {
> + tst_res(TPASS, "Kernel is not tainted");
> + }
> +}
> +
> +static struct tst_test test = {
> + .setup = setup,
> + .test_all = run,
> + .options = options,
> + .needs_tmpdir = 1,
> + .forks_child = 1
> +};
> --
> 2.23.0
>

+syzkaller mailing list FTR

Li Wang

unread,
Nov 12, 2019, 7:38:56 AM11/12/19
to Richard Palethorpe, syzkaller, automate...@yoctoproject.org, LTP List, Dmitry Vyukov
Just to try build it in LTP and hit errors:

# cd ltp-new/
# make autotools
# ./configure --with-syzkaller-repros
# make -j32
...
error: pathspec '/root/ltp-new/testcases/linux-arts' did not match any file(s) known to git
make[3]: *** [/root/ltp-new/testcases/kernel/syzkaller-repros/Makefile:26: /root/ltp-new/testcases/linux-arts/syzkaller-repros/linux] Error 1
make[3]: Leaving directory '/root/ltp-new/testcases/kernel/syzkaller-repros'
make[2]: *** [../../include/mk/generic_trunk_target.inc:93: all] Error 2
make[2]: Leaving directory '/root/ltp-new/testcases/kernel'
make[1]: *** [../include/mk/generic_trunk_target.inc:93: all] Error 2
make[1]: Leaving directory '/root/ltp-new/testcases'
make: *** [Makefile:108: testcases-all] Error 2

 
--
Mailing list info: https://lists.linux.it/listinfo/ltp


--
Regards,
Li Wang

Richard Palethorpe

unread,
Nov 12, 2019, 9:00:27 AM11/12/19
to Li Wang, Richard Palethorpe, syzkaller, automate...@yoctoproject.org, LTP List, Dmitry Vyukov
Hello,

Li Wang <liw...@redhat.com> writes:

>
>
> Just to try build it in LTP and hit errors:
>
> # cd ltp-new/
> # make autotools
> # ./configure --with-syzkaller-repros
> # make -j32
> ...
> error: pathspec '/root/ltp-new/testcases/linux-arts' did not match any
> file(s) known to git
> make[3]: *** [/root/ltp-new/testcases/kernel/syzkaller-repros/Makefile:26:
> /root/ltp-new/testcases/linux-arts/syzkaller-repros/linux] Error 1
> make[3]: Leaving directory '/root/ltp-new/testcases/kernel/syzkaller-repros'
> make[2]: *** [../../include/mk/generic_trunk_target.inc:93: all] Error 2
> make[2]: Leaving directory '/root/ltp-new/testcases/kernel'
> make[1]: *** [../include/mk/generic_trunk_target.inc:93: all] Error 2
> make[1]: Leaving directory '/root/ltp-new/testcases'
> make: *** [Makefile:108: testcases-all] Error 2
>
>

What happens if you try to pull the git submodule manually?

i.e. do git submodule update --init testcases/linux-arts

It looks like it failed on the line where it gets the submodule, so I am
wondering if you have an old git version?

--
Thank you,
Richard.

Li Wang

unread,
Nov 12, 2019, 9:11:11 AM11/12/19
to Richard Palethorpe, Richard Palethorpe, syzkaller, automate...@yoctoproject.org, LTP List, Dmitry Vyukov
On Tue, Nov 12, 2019 at 10:00 PM Richard Palethorpe <rpale...@suse.de> wrote:
Hello,

Li Wang <liw...@redhat.com> writes:

>
>
> Just to try build it in LTP and hit errors:
>
> # cd ltp-new/
> # make autotools
> # ./configure --with-syzkaller-repros
> # make -j32
> ...
> error: pathspec '/root/ltp-new/testcases/linux-arts' did not match any
> file(s) known to git
> make[3]: *** [/root/ltp-new/testcases/kernel/syzkaller-repros/Makefile:26:
> /root/ltp-new/testcases/linux-arts/syzkaller-repros/linux] Error 1
> make[3]: Leaving directory '/root/ltp-new/testcases/kernel/syzkaller-repros'
> make[2]: *** [../../include/mk/generic_trunk_target.inc:93: all] Error 2
> make[2]: Leaving directory '/root/ltp-new/testcases/kernel'
> make[1]: *** [../include/mk/generic_trunk_target.inc:93: all] Error 2
> make[1]: Leaving directory '/root/ltp-new/testcases'
> make: *** [Makefile:108: testcases-all] Error 2
>
>

What happens if you try to pull the git submodule manually?
# pwd
/root/ltp-new

# git submodule update --init testcases/linux-arts
error: pathspec 'testcases/linux-arts' did not match any file(s) known to git
 

i.e. do git submodule update --init testcases/linux-arts

It looks like it failed on the line where it gets the submodule, so I am
wondering if you have an old git version?

Not sure if that related to git-version, I'm trying to look into it.

# git --version
git version 2.23.0

# uname -r
5.3.8-300.fc31.x86_64

--
Regards,
Li Wang

Li Wang

unread,
Nov 13, 2019, 1:27:31 AM11/13/19
to Richard Palethorpe, Richard Palethorpe, syzkaller, automate...@yoctoproject.org, LTP List, Dmitry Vyukov
Hi Richard,

I have tried many times with different systems but still not working.

My question is did you add the submodule via 'git-submodule add' commands? or just modify the .gitmodules file by hand?

i.e: `git submodule add https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-arts.git testcases/linux-arts`

I don't understand why I can't see the subproject commit-id in your patch. I have to perform git-submodule-add locally again then it could compile for me.

i.e:
diff --git a/testcases/linux-arts b/testcases/linux-arts
new file mode 160000
index 0000000..07759b8
--- /dev/null
+++ b/testcases/linux-arts
@@ -0,0 +1 @@
+Subproject commit 07759b820a9cbf01333d861d8eb2613b20d1ede4

Or did I missing anything?

--
Regards,
Li Wang

Richard Palethorpe

unread,
Nov 13, 2019, 4:34:58 AM11/13/19
to Li Wang, Richard Palethorpe, Richard Palethorpe, syzkaller, automate...@yoctoproject.org, LTP List, Dmitry Vyukov
Sorry, I think it is probably my fault. I added the submodule properly,
but I set 'ignore = all' to .gitmodules which prevents the commit-id
from being added to the patchset.

I set ignore=all because I thought it would probably be best to always
get the HEAD of linux-arts, at least to begin with. Otherwise we have to
remember to update it.

--
Thank you,
Richard.

Li Wang

unread,
Nov 26, 2019, 3:18:51 AM11/26/19
to Richard Palethorpe, LTP List, automate...@yoctoproject.org, Dmitry Vyukov, syzkaller
Hi Richard,

Some more queries below.

On Thu, Nov 7, 2019 at 11:36 PM Richard Palethorpe <rpale...@suse.com> wrote:
Allows one to run the Syzkaller reproducers as part of the LTP.

...


+AC_ARG_WITH([syzkaller-repros],
+  [AC_HELP_STRING([--with-syzkaller-repros],
+    [compile and install Syzkaller reproducers (default=no)])],
+  [with_syzkaller_repros=$withval]

To strictly, the [action-if-not-given] should be added too?
 
+)
+if test "x$with_syzkaller_repros" = xyes; then
+    AC_SUBST([WITH_SYZKALLER_REPROS],["yes"])
+else
+    AC_SUBST([WITH_SYZKALLER_REPROS],["no"])
+fi
...

diff --git a/runtest/.gitignore b/runtest/.gitignore
new file mode 100644
index 000000000..2ae05bfac
--- /dev/null
+++ b/runtest/.gitignore
@@ -0,0 +1 @@
+syzkaller*

Why adding syzkaller* in here?
 
diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
index 3319b3163..0150cfb4f 100644
--- a/testcases/kernel/Makefile
+++ b/testcases/kernel/Makefile
@@ -53,6 +53,7 @@ SUBDIRS                       += connectors \
                           sched \
                           security \
                           sound \
+                          syzkaller-repros \
                           tracing \
                           uevents \

diff --git a/testcases/kernel/syzkaller-repros/.gitignore b/testcases/kernel/syzkaller-repros/.gitignore
new file mode 100644
index 000000000..dbda1c71f
--- /dev/null
+++ b/testcases/kernel/syzkaller-repros/.gitignore
@@ -0,0 +1 @@
+syzwrap
diff --git a/testcases/kernel/syzkaller-repros/Makefile b/testcases/kernel/syzkaller-repros/Makefile
new file mode 100644
...

+# Some useful compiler flags for the LTP will cause problems with the
+# syzkaller repros so the repros have seperate flags
+SYZKALLER_CFLAGS ?= -pthread
+SYZKALLER_REPROS = $(subst $(abs_top_srcdir),$(abs_top_builddir),$(SYZKALLER_REPROS_SRCS:.c=))
+$(SYZKALLER_REPROS): %: %.c
+       -@if grep -q "__NR_mmap2" $^; then \
+               M32="-m32"; \

I got compiling errors on s390x:
  gcc: error: unrecognized command line option ‘-m32’; did you mean ‘-m31’?

My other concern is syzkaller (I guess maybe) have some package dependencies, and that will break the compiler phase on the embedded system.
 
....

+       while (!waitpid(pid, &status, WNOHANG)) {
+               rem = tst_timeout_remaining();
+
+               if (!sent_kill && rem / exec_time_start < 0.5) {
+                       tst_res(TINFO, "Timeout; killing reproducer");
+
+                       TEST(kill(pid, SIGKILL));
+                       if (TST_RET == -1)
+                               tst_res(TWARN | TTERRNO, "kill() failed");
+                       else
+                               sent_kill = 1;
+               }
+
+               usleep(backoff);
+               backoff = MIN(2 * backoff, 1000000);
+       }

Force to kill a timeout test process is fine, but one thing makes me worried is that we don't do any cleanup work(e.g. release hugepage, devices or other resources) for the children, that very probably causes many additional issues in the next testing and not easy to reproduce it in a new run.
 
+
+       if (tst_taint_check()) {
+               tst_res(TFAIL, "Kernel is tainted");
+       } else {
+               tst_res(TPASS, "Kernel is not tainted");
+       }

If this is the only condition to judge if all tests pass or not, we may miss some test failure logs after running, unless we don't care about that.

Btw, I can't even finish one round for the test then system panic there. 

--
Regards,
Li Wang

Richard Palethorpe

unread,
Nov 26, 2019, 5:32:11 AM11/26/19
to Li Wang, Richard Palethorpe, LTP List, automate...@yoctoproject.org, Dmitry Vyukov, syzkaller
Hello,

Li Wang <liw...@redhat.com> writes:

> Hi Richard,
>
> Some more queries below.
>
> On Thu, Nov 7, 2019 at 11:36 PM Richard Palethorpe <rpale...@suse.com>
> wrote:
>
>> Allows one to run the Syzkaller reproducers as part of the LTP.
>>
>> ...
>>
>> +AC_ARG_WITH([syzkaller-repros],
>> + [AC_HELP_STRING([--with-syzkaller-repros],
>> + [compile and install Syzkaller reproducers (default=no)])],
>> + [with_syzkaller_repros=$withval]
>>
>
> To strictly, the [action-if-not-given] should be added too?

Were the other 'with' options updated recently to have that? I just
copied this from the other options.

>
>
>> +)
>> +if test "x$with_syzkaller_repros" = xyes; then
>> + AC_SUBST([WITH_SYZKALLER_REPROS],["yes"])
>> +else
>> + AC_SUBST([WITH_SYZKALLER_REPROS],["no"])
>> +fi
>> ...
>> diff --git a/runtest/.gitignore b/runtest/.gitignore
>> new file mode 100644
>> index 000000000..2ae05bfac
>> --- /dev/null
>> +++ b/runtest/.gitignore
>> @@ -0,0 +1 @@
>> +syzkaller*
>>
>
> Why adding syzkaller* in here?

The runtest files are automatically generated.
I have only tried these on x86_64 so far and I think that is all we can
support to begin with.

>
> My other concern is syzkaller (I guess maybe) have some package
> dependencies, and that will break the compiler phase on the embedded
> system.

This is true, the reproducers do have dependencies and it seems to vary
(randomly view some of the C files). However this is one of the reasons
why they are only installed if --with-syzkaller-repros is set.

>
>
>> ....
>> + while (!waitpid(pid, &status, WNOHANG)) {
>> + rem = tst_timeout_remaining();
>> +
>> + if (!sent_kill && rem / exec_time_start < 0.5) {
>> + tst_res(TINFO, "Timeout; killing reproducer");
>> +
>> + TEST(kill(pid, SIGKILL));
>> + if (TST_RET == -1)
>> + tst_res(TWARN | TTERRNO, "kill() failed");
>> + else
>> + sent_kill = 1;
>> + }
>> +
>> + usleep(backoff);
>> + backoff = MIN(2 * backoff, 1000000);
>> + }
>>
>
> Force to kill a timeout test process is fine, but one thing makes me
> worried is that we don't do any cleanup work(e.g. release hugepage, devices
> or other resources) for the children, that very probably causes many
> additional issues in the next testing and not easy to reproduce it in a new
> run.

The reproducer itself should clear up some of this. It is also possible
to regenerate the reproducers with more sandboxing AFAICT. However the
sandboxing itself has some requirements.

I don't know how we could possibly cleanup after every reproducer,
except by taking a complete snapshot of the system and reverting to
it. Which is what I recommend doing in the README.

This is another reason for the --with-syzkaller-repros flag. The test
runner must do extra work compared to normal LTP tests. I'm also not
sure it would be safe to run these on baremetal unless you regenerate
them with the extra sandboxing.

>
>
>> +
>> + if (tst_taint_check()) {
>> + tst_res(TFAIL, "Kernel is tainted");
>> + } else {
>> + tst_res(TPASS, "Kernel is not tainted");
>> + }
>
>
> If this is the only condition to judge if all tests pass or not, we may
> miss some test failure logs after running, unless we don't care about
> that.

They produce a lot of output, some of it might be useful for returning
TCONF (like when sandboxing is enabled in syzwrap and this stops network
devices from being created). However I think it is more important to
provide some basic functionality than work on stuff like this.

>
> Btw, I can't even finish one round for the test then system panic there.

Same. There are a lot of reproducers for unsolved bugs, plus some of
them probably shouldn't be run as root without the extra sandboxing. So
they will crash the system just by randomly deleting or overwriting
stuff.

--
Thank you,
Richard.

Petr Vorel

unread,
Nov 26, 2019, 7:42:46 AM11/26/19
to Richard Palethorpe, Li Wang, Richard Palethorpe, LTP List, automate...@yoctoproject.org, Dmitry Vyukov, syzkaller
Hi,

> >> +AC_ARG_WITH([syzkaller-repros],
> >> + [AC_HELP_STRING([--with-syzkaller-repros],
> >> + [compile and install Syzkaller reproducers (default=no)])],
> >> + [with_syzkaller_repros=$withval]


> > To strictly, the [action-if-not-given] should be added too?

> Were the other 'with' options updated recently to have that? I just
> copied this from the other options.
Yep, you'll just add
[with_syzkaller_repros=no]
(looking at the default off, probably safer for the start)

> >> diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
> >> index 3319b3163..0150cfb4f 100644
> >> --- a/testcases/kernel/Makefile
> >> +++ b/testcases/kernel/Makefile
> >> @@ -53,6 +53,7 @@ SUBDIRS += connectors \
> >> sched \
> >> security \
> >> sound \
> >> + syzkaller-repros \
> >> tracing \
> >> uevents \

> >> +# Some useful compiler flags for the LTP will cause problems with the
> >> +# syzkaller repros so the repros have seperate flags
> >> +SYZKALLER_CFLAGS ?= -pthread
> >> +SYZKALLER_REPROS = $(subst
> >> $(abs_top_srcdir),$(abs_top_builddir),$(SYZKALLER_REPROS_SRCS:.c=))
> >> +$(SYZKALLER_REPROS): %: %.c
> >> + -@if grep -q "__NR_mmap2" $^; then \
> >> + M32="-m32"; \


> > I got compiling errors on s390x:
> > gcc: error: unrecognized command line option ‘-m32’; did you mean
> > ‘-m31’?

> I have only tried these on x86_64 so far and I think that is all we can
> support to begin with.

Maybe filter it out in testcases/kernel/Makefile with something like this:
ifneq (,$(filter $(HOST_CPU),x86 x86_64))
FILTER_OUT_DIRS += syzkaller-repros
endif

> > My other concern is syzkaller (I guess maybe) have some package
> > dependencies, and that will break the compiler phase on the embedded
> > system.

> This is true, the reproducers do have dependencies and it seems to vary
> (randomly view some of the C files). However this is one of the reasons
> why they are only installed if --with-syzkaller-repros is set.
Maybe later we manage to generate autotools config based on pkg-config.

Kind regards,
Petr

Richard Palethorpe

unread,
Dec 4, 2019, 5:31:40 AM12/4/19
to l...@lists.linux.it, Richard Palethorpe, syzkaller
Allows one to run the Syzkaller reproducers as part of the LTP.

Signed-off-by: Richard Palethorpe <rpale...@suse.com>
---

V2:

* Will now refuse to compile on anything other than x86_64, because I haven't
tested them on anything else.

* Hopefully fixed problem with submodule not being found because I didn't
include a commit reference.

* Added explicity 'no' value if --with-syzkaller-repros is not present

* Reduced the default timeout in the test to 20 seconds. I found this allows
me to complete testing in reasonable time.

.gitmodules | 4 +
configure.ac | 12 ++
include/mk/features.mk.in | 2 +
runtest/.gitignore | 1 +
testcases/kernel/Makefile | 1 +
testcases/kernel/syzkaller-repros/.gitignore | 1 +
testcases/kernel/syzkaller-repros/Makefile | 105 +++++++++++++++
testcases/kernel/syzkaller-repros/README.md | 45 +++++++
testcases/kernel/syzkaller-repros/syzwrap.c | 134 +++++++++++++++++++
testcases/linux-arts | 1 +
10 files changed, 306 insertions(+)
create mode 100644 runtest/.gitignore
create mode 100644 testcases/kernel/syzkaller-repros/.gitignore
create mode 100644 testcases/kernel/syzkaller-repros/Makefile
create mode 100644 testcases/kernel/syzkaller-repros/README.md
create mode 100644 testcases/kernel/syzkaller-repros/syzwrap.c
create mode 160000 testcases/linux-arts

diff --git a/.gitmodules b/.gitmodules
index 1c9e9c38a..2b9e836e6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,7 @@
[submodule "testcases/kernel/mce-test"]
path = testcases/kernel/mce-test
url = git://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/mce-test.git
+[submodule "testcases/linux-arts"]
+ path = testcases/linux-arts
+ url = https://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-arts.git
+ shallow = true
diff --git a/configure.ac b/configure.ac
index 50d14967d..c8ae42121 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,6 +187,18 @@ else
AC_SUBST([WITH_OPEN_POSIX_TESTSUITE],["no"])
fi

+AC_ARG_WITH([syzkaller-repros],
+ [AC_HELP_STRING([--with-syzkaller-repros],
+ [compile and install Syzkaller reproducers (default=no)])],
+ [with_syzkaller_repros=$withval]
+ [with_syzkaller_repros=no]
+)
+if test "x$with_syzkaller_repros" = xyes; then
+ AC_SUBST([WITH_SYZKALLER_REPROS],["yes"])
+else
+ AC_SUBST([WITH_SYZKALLER_REPROS],["no"])
+fi
+
# TODO: testcases/realtime requires bash and python.
AC_ARG_WITH([realtime-testsuite],
[AC_HELP_STRING([--with-realtime-testsuite],
diff --git a/include/mk/features.mk.in b/include/mk/features.mk.in
index 8e561b738..3ab7f4721 100644
--- a/include/mk/features.mk.in
+++ b/include/mk/features.mk.in
@@ -47,3 +47,5 @@ WITH_REALTIME_TESTSUITE := no
else
WITH_REALTIME_TESTSUITE := @WITH_REALTIME_TESTSUITE@
endif
+
+WITH_SYZKALLER_REPROS := @WITH_SYZKALLER_REPROS@
diff --git a/runtest/.gitignore b/runtest/.gitignore
new file mode 100644
index 000000000..2ae05bfac
--- /dev/null
+++ b/runtest/.gitignore
@@ -0,0 +1 @@
+syzkaller*
diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
index 3319b3163..0150cfb4f 100644
--- a/testcases/kernel/Makefile
+++ b/testcases/kernel/Makefile
@@ -53,6 +53,7 @@ SUBDIRS += connectors \
sched \
security \
sound \
+ syzkaller-repros \
tracing \
uevents \

diff --git a/testcases/kernel/syzkaller-repros/.gitignore b/testcases/kernel/syzkaller-repros/.gitignore
new file mode 100644
index 000000000..dbda1c71f
--- /dev/null
+++ b/testcases/kernel/syzkaller-repros/.gitignore
@@ -0,0 +1 @@
+syzwrap
diff --git a/testcases/kernel/syzkaller-repros/Makefile b/testcases/kernel/syzkaller-repros/Makefile
new file mode 100644
index 000000000..a3acf9647
--- /dev/null
+++ b/testcases/kernel/syzkaller-repros/Makefile
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2019 Linux Test Project
+
+top_srcdir ?= ../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+CFLAGS += -D_GNU_SOURCE
+
+ifeq ($(WITH_SYZKALLER_REPROS),yes)
+
+# This is mainly due to the -m32 flag, but there could be other problems.
+ifneq ($(HOST_CPU), x86_64))
+$(error "We currently only support building the Syzkaller reproducers on x86_64")
+endif
+
+# The number of reproducers in each runtest file
+SYZKALLER_RUNFILES_SIZE ?= 100
+
+# Extra arguments to pass to syzwrap. Uncomment the below to add some
+# sandboxing.
+# SYZWRAP_ARGS ?= -s
+
+# Location where reproducers are installed
+SYZKALLER_INSTALL_DIR ?= $(abspath $(DESTDIR)/$(prefix)/testcases/bin)
+
+# If the reproducers directory is missing then we automatically clone the repo.
+# We then have to call make recursively to revaluate the targets
+SYZKALLER_REPROS_DIR ?= $(abs_top_srcdir)/testcases/linux-arts/syzkaller-repros/linux
+$(SYZKALLER_REPROS_DIR):
+ git submodule update --init $(abs_top_srcdir)/testcases/linux-arts
+ $(MAKE) syzkaller_runfiles
+
+SYZKALLER_REPROS_SRCS = $(wildcard $(SYZKALLER_REPROS_DIR)/*.c)
+
+# Some useful compiler flags for the LTP will cause problems with the
+# syzkaller repros so the repros have seperate flags
+SYZKALLER_CFLAGS ?= -pthread
+SYZKALLER_REPROS = $(subst $(abs_top_srcdir),$(abs_top_builddir),$(SYZKALLER_REPROS_SRCS:.c=))
+$(SYZKALLER_REPROS): %: %.c
+ -@if grep -q "__NR_mmap2" $^; then \
+ M32="-m32"; \
new file mode 100644
new file mode 100644
index 000000000..c8c95e750
--- /dev/null
+++ b/testcases/kernel/syzkaller-repros/syzwrap.c
@@ -0,0 +1,134 @@
+ while (!waitpid(pid, &status, WNOHANG)) {
+ rem = tst_timeout_remaining();
+
+ if (!sent_kill && rem / exec_time_start < 0.5) {
+ tst_res(TINFO, "Timeout; killing reproducer");
+
+ TEST(kill(pid, SIGKILL));
+ if (TST_RET == -1)
+ tst_res(TWARN | TTERRNO, "kill() failed");
+ else
+ sent_kill = 1;
+ }
+
+ usleep(backoff);
+ backoff = MIN(2 * backoff, 1000000);
+ }
+
+ if (tst_taint_check()) {
+ tst_res(TFAIL, "Kernel is tainted");
+ } else {
+ tst_res(TPASS, "Kernel is not tainted");
+ }
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .options = options,
+ .needs_tmpdir = 1,
+ .forks_child = 1,
+ .timeout = 20
+};
diff --git a/testcases/linux-arts b/testcases/linux-arts
new file mode 160000
index 000000000..07759b820
--- /dev/null
+++ b/testcases/linux-arts
@@ -0,0 +1 @@
+Subproject commit 07759b820a9cbf01333d861d8eb2613b20d1ede4
--
2.23.0

Dmitry Vyukov

unread,
Feb 12, 2020, 3:51:04 AM2/12/20
to Richard Palethorpe, l...@lists.linux.it, syzkaller
On Wed, Dec 4, 2019 at 11:31 AM Richard Palethorpe <rpale...@suse.com> wrote:
>
> Allows one to run the Syzkaller reproducers as part of the LTP.
>
> Signed-off-by: Richard Palethorpe <rpale...@suse.com>
> ---
>
> V2:
>
> * Will now refuse to compile on anything other than x86_64, because I haven't
> tested them on anything else.
>
> * Hopefully fixed problem with submodule not being found because I didn't
> include a commit reference.
>
> * Added explicity 'no' value if --with-syzkaller-repros is not present
>
> * Reduced the default timeout in the test to 20 seconds. I found this allows
> me to complete testing in reasonable time.

What's the status of this? This wasn't merged yet, right?
I don't see this here:
https://github.com/linux-test-project/ltp/tree/master/testcases/kernel

People are asking how these tests can be run:
https://github.com/dvyukov/syzkaller-repros/pull/1#issuecomment-583996369
> --
> You received this message because you are subscribed to the Google Groups "syzkaller" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to syzkaller+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/syzkaller/20191204103120.29440-1-rpalethorpe%40suse.com.

Richard Palethorpe

unread,
Feb 19, 2020, 3:27:52 AM2/19/20
to Dmitry Vyukov, Richard Palethorpe, syzkaller, l...@lists.linux.it
Hello Dmitry,

Dmitry Vyukov via ltp <l...@lists.linux.it> writes:

> On Wed, Dec 4, 2019 at 11:31 AM Richard Palethorpe <rpale...@suse.com> wrote:
>>
>> Allows one to run the Syzkaller reproducers as part of the LTP.
>>
>> Signed-off-by: Richard Palethorpe <rpale...@suse.com>
>> ---
>>
>> V2:
>>
>> * Will now refuse to compile on anything other than x86_64, because I haven't
>> tested them on anything else.
>>
>> * Hopefully fixed problem with submodule not being found because I didn't
>> include a commit reference.
>>
>> * Added explicity 'no' value if --with-syzkaller-repros is not present
>>
>> * Reduced the default timeout in the test to 20 seconds. I found this allows
>> me to complete testing in reasonable time.
>
> What's the status of this? This wasn't merged yet, right?
> I don't see this here:
> https://github.com/linux-test-project/ltp/tree/master/testcases/kernel

Yeah, it fell to one side due to the LTP release, SUSE Hackweek and lack
of feedback. Hopefully we can get it merged soon however.

>
> People are asking how these tests can be run:
> https://github.com/dvyukov/syzkaller-repros/pull/1#issuecomment-583996369

I responded with some links for using it.
--
Thank you,
Richard.

Cyril Hrubis

unread,
Feb 19, 2020, 5:35:07 AM2/19/20
to Richard Palethorpe, Dmitry Vyukov, syzkaller, Richard Palethorpe, l...@lists.linux.it
Hi!
> >> Allows one to run the Syzkaller reproducers as part of the LTP.
> >>
> >> Signed-off-by: Richard Palethorpe <rpale...@suse.com>
> >> ---
> >>
> >> V2:
> >>
> >> * Will now refuse to compile on anything other than x86_64, because I haven't
> >> tested them on anything else.
> >>
> >> * Hopefully fixed problem with submodule not being found because I didn't
> >> include a commit reference.
> >>
> >> * Added explicity 'no' value if --with-syzkaller-repros is not present
> >>
> >> * Reduced the default timeout in the test to 20 seconds. I found this allows
> >> me to complete testing in reasonable time.
> >
> > What's the status of this? This wasn't merged yet, right?
> > I don't see this here:
> > https://github.com/linux-test-project/ltp/tree/master/testcases/kernel
>
> Yeah, it fell to one side due to the LTP release, SUSE Hackweek and lack
> of feedback. Hopefully we can get it merged soon however.

You don't forget about FOSDEM. Unfortunatelly we have managed to
accumulate quite a backlog at the start of the year.

However I do plan to return to this once things settle down a bit.

--
Cyril Hrubis
chr...@suse.cz
Reply all
Reply to author
Forward
0 new messages