linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Kernel WARNING in dio_complete found by syzkaller
@ 2018-03-12  4:02 Kaipeng Zeng
  2018-03-12  4:17 ` Eric Biggers
  0 siblings, 1 reply; 2+ messages in thread
From: Kaipeng Zeng @ 2018-03-12  4:02 UTC (permalink / raw)
  To: viro, linux-fsdevel; +Cc: syzkaller

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Kernel WARNING in dio_complete found by syzkaller
  2018-03-12  4:02 Kernel WARNING in dio_complete found by syzkaller Kaipeng Zeng
@ 2018-03-12  4:17 ` Eric Biggers
  0 siblings, 0 replies; 2+ messages in thread
From: Eric Biggers @ 2018-03-12  4:17 UTC (permalink / raw)
  To: Kaipeng Zeng; +Cc: viro, linux-fsdevel, syzkaller, Darrick J. Wong

Hi Kaipeng,

On Mon, Mar 12, 2018 at 12:02:12PM +0800, Kaipeng Zeng wrote:
> Kernel version: 4.14.0
> Kernel configure: defconfig
> syzkaller crepro:
> // autogenerated by syzkaller (http://github.com/google/syzkaller)
> 
[...]
> ------------[ 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

This WARN was already removed by commit 5a9d929d6e132 ("iomap: report collisions
between directio and buffered writes to userspace").

As a side note, you generally shouldn't waste time testing v4.14.0.  The current
version in the 4.14-stable series is already v4.14.26, so by fuzzing v4.14.0 you
will find bugs that were already fixed.

That being said, this particular fix wasn't Cc'ed to stable so it isn't in
4.14-stable yet.  Unless there are objections I suggest sending a request to
stable@vger.kernel.org to have it applied.

Thanks,

Eric

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-03-12  4:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12  4:02 Kernel WARNING in dio_complete found by syzkaller Kaipeng Zeng
2018-03-12  4:17 ` Eric Biggers

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).