From: Kaipeng Zeng <kaipeng94@gmail.com>
To: viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org
Cc: syzkaller@googlegroups.com
Subject: Kernel WARNING in dio_complete found by syzkaller
Date: Mon, 12 Mar 2018 12:02:12 +0800 [thread overview]
Message-ID: <CAHk8ZdtCHeYYHkDKfUi0_2__YyNACT5snHOTHhYawrMLS1+mrA@mail.gmail.com> (raw)
Kernel version: 4.14.0
Kernel configure: defconfig
syzkaller crepro:
// autogenerated by syzkaller (http://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <linux/futex.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
__attribute__((noreturn)) static void doexit(int status)
{
volatile unsigned i;
syscall(__NR_exit_group, status);
for (i = 0;; i++) {
}
}
#include <setjmp.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
static __thread int skip_segv;
static __thread jmp_buf segv_env;
static void segv_handler(int sig, siginfo_t* info, void* uctx)
{
uintptr_t addr = (uintptr_t)info->si_addr;
const uintptr_t prog_start = 1 << 20;
const uintptr_t prog_end = 100 << 20;
if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED) &&
(addr < prog_start || addr > prog_end)) {
_longjmp(segv_env, 1);
}
doexit(sig);
}
static void install_segv_handler()
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = segv_handler;
sa.sa_flags = SA_NODEFER | SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
}
#define NONFAILING(...) \
{ \
__atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
if (_setjmp(segv_env) == 0) { \
__VA_ARGS__; \
} \
__atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
}
static void test();
void loop()
{
while (1) {
test();
}
}
struct thread_t {
int created, running, call;
pthread_t th;
};
static struct thread_t threads[16];
static void execute_call(int call);
static int running;
static int collide;
static void* thr(void* arg)
{
struct thread_t* th = (struct thread_t*)arg;
for (;;) {
while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE))
syscall(SYS_futex, &th->running, FUTEX_WAIT, 0, 0);
execute_call(th->call);
__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
__atomic_store_n(&th->running, 0, __ATOMIC_RELEASE);
syscall(SYS_futex, &th->running, FUTEX_WAKE);
}
return 0;
}
static void execute(int num_calls)
{
int call, thread;
running = 0;
for (call = 0; call < num_calls; call++) {
for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) {
struct thread_t* th = &threads[thread];
if (!th->created) {
th->created = 1;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 128 << 10);
pthread_create(&th->th, &attr, thr, th);
}
if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) {
th->call = call;
__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
__atomic_store_n(&th->running, 1, __ATOMIC_RELEASE);
syscall(SYS_futex, &th->running, FUTEX_WAKE);
if (collide && call % 2)
break;
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 20 * 1000 * 1000;
syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts);
if (running)
usleep((call == num_calls - 1) ? 10000 : 1000);
break;
}
}
}
}
long r[2];
uint64_t procid;
void execute_call(int call)
{
switch (call) {
case 0:
syscall(__NR_mmap, 0x20000000, 0x1000, 3, 0x32, -1, 0);
break;
case 1:
NONFAILING(memcpy(
(void*)0x20000ffe,
"\x2f\x72\x6f\x6f\x74\x2f\x74\x65\x73\x74\x2e\x74\x78\x74\x00\x00\x00",
17));
r[0] = syscall(__NR_open, 0x20000ffe, 0x403e, 0);
break;
case 2:
syscall(__NR_mmap, 0x20001000, 0x1000, 3, 0x32, -1, 0);
break;
case 3:
syscall(__NR_write, -1, 0x20001000, 0);
break;
case 4:
syscall(__NR_mmap, 0x20000000, 0x2000, 2, 0x11, r[0], 0);
break;
case 5:
NONFAILING(memcpy((void*)0x20000fef, "/root/tmp/test.c", 17));
syscall(__NR_open, 0x20000fef, 0, 0);
break;
case 6:
syscall(__NR_mmap, 0x20002000, 0x1000, 3, 0x32, -1, 0);
break;
case 7:
NONFAILING(memcpy(
(void*)0x20000ffe,
"\x2f\x72\x6f\x6f\x74\x2f\x74\x65\x73\x74\x2e\x74\x78\x74\x00\x00\x00",
17));
r[1] = syscall(__NR_open, 0x20000ffe, 0, 0);
break;
case 8:
syscall(__NR_close, r[1]);
break;
case 9:
NONFAILING(memcpy(
(void*)0x20000ffe,
"\x2f\x72\x6f\x6f\x74\x2f\x74\x65\x73\x74\x2e\x74\x78\x74\x00\x00\x00",
17));
syscall(__NR_open, 0x20000ffe, 0x403e, 0);
break;
case 10:
syscall(__NR_write, r[1], 0x20002000, 0xfffffe7f);
break;
}
}
void test()
{
memset(r, -1, sizeof(r));
execute(11);
collide = 1;
execute(11);
}
int main()
{
for (procid = 0; procid < 8; procid++) {
if (fork() == 0) {
install_segv_handler();
for (;;) {
loop();
}
}
}
sleep(1000000);
return 0;
}
log:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 6473 at
/root/linux-source-4.14/fs/direct-io.c:293 dio_complete+0x58e/0x840
Kernel panic - not syncing: panic_on_warn set ...
CPU: 0 PID: 6473 Comm: syz-executor0 Not tainted 4.14.7 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Call Trace:
dump_stack+0x83/0xb8
panic+0x1bc/0x3b1
__warn+0x1c9/0x1e0
report_bug+0x213/0x2d0
fixup_bug.part.12+0x3c/0x90
do_error_trap+0x65/0xb0
do_invalid_op+0x20/0x30
invalid_op+0x18/0x20
RIP: 0010:dio_complete+0x58e/0x840
RSP: 0018:ffff880065e1f5c8 EFLAGS: 00010287
RAX: 0000000000010000 RBX: ffff880037e14340 RCX: ffffc90000576000
RDX: 0000000000002359 RSI: ffffffff8176382e RDI: ffff880062e4166c
RBP: ffff880065e1f610 R08: ffff880065e1f430 R09: ffff88003d8013c0
R10: ffff880065e1f117 R11: ffffed000cbc3e23 R12: ffff880062e417d8
R13: 0000000000001000 R14: 0000000000000000 R15: 0000000000001000
do_blockdev_direct_IO+0x6239/0x7f90
__blockdev_direct_IO+0xa2/0xd0
ext4_direct_IO+0x7b5/0x1290 [ext4]
generic_file_direct_write+0x22a/0x420
__generic_file_write_iter+0x227/0x5b0
ext4_file_write_iter+0x2d5/0xf00 [ext4]
new_sync_write+0x3d5/0x5f0
__vfs_write+0xe8/0x120
vfs_write+0x18c/0x500
SyS_write+0xd8/0x1b0
system_call_fast_compare_end+0xc/0x97
RIP: 0033:0x452f39
RSP: 002b:00007fda76cb7c68 EFLAGS: 00000216 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 000000000070bea0 RCX: 0000000000452f39
RDX: 0000000000001000 RSI: 0000000020000000 RDI: 0000000000000013
RBP: 0000000000000652 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000216 R12: 00000000006de850
R13: 00000000ffffffff R14: 00007fda76cb86d4 R15: 000000000049f371
Dumping ftrace buffer:
(ftrace buffer empty)
Kernel Offset: disabled
next reply other threads:[~2018-03-12 4:02 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-12 4:02 Kaipeng Zeng [this message]
2018-03-12 4:17 ` Kernel WARNING in dio_complete found by syzkaller Eric Biggers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAHk8ZdtCHeYYHkDKfUi0_2__YyNACT5snHOTHhYawrMLS1+mrA@mail.gmail.com \
--to=kaipeng94@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=syzkaller@googlegroups.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).