linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* net/sctp: null-ptr-deref in sctp_inet_listen
@ 2016-11-07 21:44 Andrey Konovalov
  2016-11-08 10:06 ` Xin Long
  0 siblings, 1 reply; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-07 21:44 UTC (permalink / raw)
  To: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp, netdev, LKML
  Cc: Dmitry Vyukov, Alexander Potapenko, Kostya Serebryany,
	Eric Dumazet, syzkaller

[-- Attachment #1: Type: text/plain, Size: 1969 bytes --]

Hi,

I've got the following error report while running the syzkaller fuzzer:

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN
Modules linked in:
CPU: 1 PID: 3851 Comm: a.out Not tainted 4.9.0-rc4+ #354
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
task: ffff880065f1d800 task.stack: ffff880063840000
RIP: 0010:[<ffffffff8394151b>]  [<ffffffff8394151b>]
sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
RSP: 0018:ffff880063847dd0  EFLAGS: 00010202
RAX: dffffc0000000000 RBX: 1ffff1000c708fbd RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
RBP: ffff880063847e70 R08: dffffc0000000000 R09: dffffc0000000000
R10: 0000000000000002 R11: 0000000000000002 R12: ffff88006b350800
R13: 0000000000000000 R14: 1ffff1000d66a1a5 R15: 0000000000000000
FS:  00007fd1f0f3d7c0(0000) GS:ffff88006cd00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000000 CR3: 0000000064af9000 CR4: 00000000000006e0
Stack:
 ffff880063847de0 ffff880066165900 ffff88006b350d20 0000000041b58ab3
 ffffffff847ff589 ffffffff83941280 dffffc0000000000 0000000000000000
 ffff880069b9f740 0000000000000000 ffff880063847e38 ffffffff819f04ef
Call Trace:
 [<     inline     >] SYSC_listen net/socket.c:1396
 [<ffffffff82b73cf6>] SyS_listen+0x206/0x250 net/socket.c:1382
 [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
Code: 00 0f 85 f4 04 00 00 4d 8b ac 24 28 05 00 00 49 b8 00 00 00 00
00 fc ff df 49 8d 7d 02 48 89 fe 49 89 fa 48 c1 ee 03 41 83 e2 07 <46>
0f b6 0c 06 41 83 c2 01 45 38 ca 7c 09 45 84 c9 0f 85 87 04
RIP  [<ffffffff8394151b>] sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
 RSP <ffff880063847dd0>
---[ end trace f2b501fc22999b37 ]---

A reproducer is attached.

On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).

Thanks!

[-- Attachment #2: sctp-listen-null-poc.c --]
[-- Type: application/octet-stream, Size: 5968 bytes --]

// autogenerated by syzkaller (http://github.com/google/syzkaller)

#ifndef __NR_syz_fuseblk_mount
#define __NR_syz_fuseblk_mount 1000005
#endif
#ifndef __NR_syz_open_dev
#define __NR_syz_open_dev 1000002
#endif
#ifndef __NR_syz_test
#define __NR_syz_test 1000001
#endif
#ifndef __NR_socket
#define __NR_socket 41
#endif
#ifndef __NR_shutdown
#define __NR_shutdown 48
#endif
#ifndef __NR_listen
#define __NR_listen 50
#endif
#ifndef __NR_syz_open_pts
#define __NR_syz_open_pts 1000003
#endif
#ifndef __NR_mmap
#define __NR_mmap 9
#endif
#ifndef __NR_setsockopt
#define __NR_setsockopt 54
#endif
#ifndef __NR_syz_fuse_mount
#define __NR_syz_fuse_mount 1000004
#endif

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>

#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <pthread.h>
#include <setjmp.h>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

__thread int skip_segv;
__thread jmp_buf segv_env;

static void segv_handler(int sig, siginfo_t* info, void* uctx)
{
  if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
    _longjmp(segv_env, 1);
  exit(sig);
}

static void install_segv_handler()
{
  struct sigaction sa;
  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 uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
{
  if (a0 == 0xc || a0 == 0xb) {

    char buf[128];
    sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block",
            (uint8_t)a1, (uint8_t)a2);
    return open(buf, O_RDWR, 0);
  } else {

    char buf[1024];
    char* hash;
    strncpy(buf, (char*)a0, sizeof(buf));
    buf[sizeof(buf) - 1] = 0;
    while ((hash = strchr(buf, '#'))) {
      *hash = '0' + (char)(a1 % 10);
      a1 /= 10;
    }
    return open(buf, a2, 0);
  }
}

static uintptr_t syz_open_pts(uintptr_t a0, uintptr_t a1)
{

  int ptyno = 0;
  if (ioctl(a0, TIOCGPTN, &ptyno))
    return -1;
  char buf[128];
  sprintf(buf, "/dev/pts/%d", ptyno);
  return open(buf, a1, 0);
}

static uintptr_t syz_fuse_mount(uintptr_t a0, uintptr_t a1,
                                uintptr_t a2, uintptr_t a3,
                                uintptr_t a4, uintptr_t a5)
{

  uint64_t target = a0;
  uint64_t mode = a1;
  uint64_t uid = a2;
  uint64_t gid = a3;
  uint64_t maxread = a4;
  uint64_t flags = a5;

  int fd = open("/dev/fuse", O_RDWR);
  if (fd == -1)
    return fd;
  char buf[1024];
  sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
          (long)uid, (long)gid, (unsigned)mode & ~3u);
  if (maxread != 0)
    sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
  if (mode & 1)
    strcat(buf, ",default_permissions");
  if (mode & 2)
    strcat(buf, ",allow_other");
  syscall(SYS_mount, "", target, "fuse", flags, buf);

  return fd;
}

static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1,
                                   uintptr_t a2, uintptr_t a3,
                                   uintptr_t a4, uintptr_t a5,
                                   uintptr_t a6, uintptr_t a7)
{

  uint64_t target = a0;
  uint64_t blkdev = a1;
  uint64_t mode = a2;
  uint64_t uid = a3;
  uint64_t gid = a4;
  uint64_t maxread = a5;
  uint64_t blksize = a6;
  uint64_t flags = a7;

  int fd = open("/dev/fuse", O_RDWR);
  if (fd == -1)
    return fd;
  if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)))
    return fd;
  char buf[256];
  sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
          (long)uid, (long)gid, (unsigned)mode & ~3u);
  if (maxread != 0)
    sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
  if (blksize != 0)
    sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
  if (mode & 1)
    strcat(buf, ",default_permissions");
  if (mode & 2)
    strcat(buf, ",allow_other");
  syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf);

  return fd;
}

static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
                                 uintptr_t a2, uintptr_t a3,
                                 uintptr_t a4, uintptr_t a5,
                                 uintptr_t a6, uintptr_t a7,
                                 uintptr_t a8)
{
  switch (nr) {
  default:
    return syscall(nr, a0, a1, a2, a3, a4, a5);
  case __NR_syz_test:
    return 0;
  case __NR_syz_open_dev:
    return syz_open_dev(a0, a1, a2);
  case __NR_syz_open_pts:
    return syz_open_pts(a0, a1);
  case __NR_syz_fuse_mount:
    return syz_fuse_mount(a0, a1, a2, a3, a4, a5);
  case __NR_syz_fuseblk_mount:
    return syz_fuseblk_mount(a0, a1, a2, a3, a4, a5, a6, a7);
  }
}

long r[6];

int main()
{
  install_segv_handler();
  memset(r, -1, sizeof(r));
  r[0] = execute_syscall(__NR_mmap, 0x20000000ul, 0xa000ul, 0x3ul,
                         0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
  r[1] = execute_syscall(__NR_socket, 0xaul, 0x1ul, 0x84ul, 0, 0, 0, 0,
                         0, 0);
  NONFAILING(*(uint32_t*)0x20000000 = (uint32_t)0x7);
  r[3] = execute_syscall(__NR_setsockopt, r[1], 0x1ul, 0x2ul,
                         0x20000000ul, 0x4ul, 0, 0, 0, 0);
  r[4] =
      execute_syscall(__NR_shutdown, r[1], 0x1ul, 0, 0, 0, 0, 0, 0, 0);
  r[5] = execute_syscall(__NR_listen, r[1], 0x0ul, 0, 0, 0, 0, 0, 0, 0);
  return 0;
}

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

* Re: net/sctp: null-ptr-deref in sctp_inet_listen
  2016-11-07 21:44 net/sctp: null-ptr-deref in sctp_inet_listen Andrey Konovalov
@ 2016-11-08 10:06 ` Xin Long
  2016-11-08 18:46   ` Andrey Konovalov
  0 siblings, 1 reply; 5+ messages in thread
From: Xin Long @ 2016-11-08 10:06 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp, netdev,
	LKML, Dmitry Vyukov, Alexander Potapenko, Kostya Serebryany,
	Eric Dumazet, syzkaller, Marcelo Ricardo Leitner

On Tue, Nov 8, 2016 at 5:44 AM, Andrey Konovalov <andreyknvl@google.com> wrote:
> Hi,
>
> I've got the following error report while running the syzkaller fuzzer:
>
> kasan: CONFIG_KASAN_INLINE enabled
> kasan: GPF could be caused by NULL-ptr deref or user memory access
> general protection fault: 0000 [#1] SMP KASAN
> Modules linked in:
> CPU: 1 PID: 3851 Comm: a.out Not tainted 4.9.0-rc4+ #354
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> task: ffff880065f1d800 task.stack: ffff880063840000
> RIP: 0010:[<ffffffff8394151b>]  [<ffffffff8394151b>]
> sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
> RSP: 0018:ffff880063847dd0  EFLAGS: 00010202
> RAX: dffffc0000000000 RBX: 1ffff1000c708fbd RCX: 0000000000000000
> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
> RBP: ffff880063847e70 R08: dffffc0000000000 R09: dffffc0000000000
> R10: 0000000000000002 R11: 0000000000000002 R12: ffff88006b350800
> R13: 0000000000000000 R14: 1ffff1000d66a1a5 R15: 0000000000000000
> FS:  00007fd1f0f3d7c0(0000) GS:ffff88006cd00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000020000000 CR3: 0000000064af9000 CR4: 00000000000006e0
> Stack:
>  ffff880063847de0 ffff880066165900 ffff88006b350d20 0000000041b58ab3
>  ffffffff847ff589 ffffffff83941280 dffffc0000000000 0000000000000000
>  ffff880069b9f740 0000000000000000 ffff880063847e38 ffffffff819f04ef
> Call Trace:
>  [<     inline     >] SYSC_listen net/socket.c:1396
>  [<ffffffff82b73cf6>] SyS_listen+0x206/0x250 net/socket.c:1382
>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> Code: 00 0f 85 f4 04 00 00 4d 8b ac 24 28 05 00 00 49 b8 00 00 00 00
> 00 fc ff df 49 8d 7d 02 48 89 fe 49 89 fa 48 c1 ee 03 41 83 e2 07 <46>
> 0f b6 0c 06 41 83 c2 01 45 38 ca 7c 09 45 84 c9 0f 85 87 04
> RIP  [<ffffffff8394151b>] sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
>  RSP <ffff880063847dd0>
> ---[ end trace f2b501fc22999b37 ]---
>
> A reproducer is attached.
>
> On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).
>
This is a shutdown injection issue.
sctp_shutdown need a sk->state check, just like tcp_shutdown:

--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4287,7 +4287,8 @@ static void sctp_shutdown(struct sock *sk, int how)
        if (!sctp_style(sk, TCP))
                return;

-       if (how & SEND_SHUTDOWN) {
+       if (how & SEND_SHUTDOWN &&
+           (1 << sk->sk_state) & (SCTP_SS_ESTABLISHED | SCTP_SS_CLOSING)) {
                sk->sk_state = SCTP_SS_CLOSING;
                ep = sctp_sk(sk)->ep;
                if (!list_empty(&ep->asocs)) {

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

* Re: net/sctp: null-ptr-deref in sctp_inet_listen
  2016-11-08 10:06 ` Xin Long
@ 2016-11-08 18:46   ` Andrey Konovalov
  2016-11-09  3:32     ` Xin Long
  0 siblings, 1 reply; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-08 18:46 UTC (permalink / raw)
  To: Xin Long
  Cc: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp, netdev,
	LKML, Dmitry Vyukov, Alexander Potapenko, Kostya Serebryany,
	Eric Dumazet, syzkaller, Marcelo Ricardo Leitner

Hi Xin,

Your patch seems to be fixing the issue.

Tested-by: Andrey Konovalov <andreyknvl@google.com>

Thanks!

On Tue, Nov 8, 2016 at 11:06 AM, Xin Long <lucien.xin@gmail.com> wrote:
> On Tue, Nov 8, 2016 at 5:44 AM, Andrey Konovalov <andreyknvl@google.com> wrote:
>> Hi,
>>
>> I've got the following error report while running the syzkaller fuzzer:
>>
>> kasan: CONFIG_KASAN_INLINE enabled
>> kasan: GPF could be caused by NULL-ptr deref or user memory access
>> general protection fault: 0000 [#1] SMP KASAN
>> Modules linked in:
>> CPU: 1 PID: 3851 Comm: a.out Not tainted 4.9.0-rc4+ #354
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>> task: ffff880065f1d800 task.stack: ffff880063840000
>> RIP: 0010:[<ffffffff8394151b>]  [<ffffffff8394151b>]
>> sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
>> RSP: 0018:ffff880063847dd0  EFLAGS: 00010202
>> RAX: dffffc0000000000 RBX: 1ffff1000c708fbd RCX: 0000000000000000
>> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
>> RBP: ffff880063847e70 R08: dffffc0000000000 R09: dffffc0000000000
>> R10: 0000000000000002 R11: 0000000000000002 R12: ffff88006b350800
>> R13: 0000000000000000 R14: 1ffff1000d66a1a5 R15: 0000000000000000
>> FS:  00007fd1f0f3d7c0(0000) GS:ffff88006cd00000(0000) knlGS:0000000000000000
>> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>> CR2: 0000000020000000 CR3: 0000000064af9000 CR4: 00000000000006e0
>> Stack:
>>  ffff880063847de0 ffff880066165900 ffff88006b350d20 0000000041b58ab3
>>  ffffffff847ff589 ffffffff83941280 dffffc0000000000 0000000000000000
>>  ffff880069b9f740 0000000000000000 ffff880063847e38 ffffffff819f04ef
>> Call Trace:
>>  [<     inline     >] SYSC_listen net/socket.c:1396
>>  [<ffffffff82b73cf6>] SyS_listen+0x206/0x250 net/socket.c:1382
>>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>> Code: 00 0f 85 f4 04 00 00 4d 8b ac 24 28 05 00 00 49 b8 00 00 00 00
>> 00 fc ff df 49 8d 7d 02 48 89 fe 49 89 fa 48 c1 ee 03 41 83 e2 07 <46>
>> 0f b6 0c 06 41 83 c2 01 45 38 ca 7c 09 45 84 c9 0f 85 87 04
>> RIP  [<ffffffff8394151b>] sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
>>  RSP <ffff880063847dd0>
>> ---[ end trace f2b501fc22999b37 ]---
>>
>> A reproducer is attached.
>>
>> On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).
>>
> This is a shutdown injection issue.
> sctp_shutdown need a sk->state check, just like tcp_shutdown:
>
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -4287,7 +4287,8 @@ static void sctp_shutdown(struct sock *sk, int how)
>         if (!sctp_style(sk, TCP))
>                 return;
>
> -       if (how & SEND_SHUTDOWN) {
> +       if (how & SEND_SHUTDOWN &&
> +           (1 << sk->sk_state) & (SCTP_SS_ESTABLISHED | SCTP_SS_CLOSING)) {
>                 sk->sk_state = SCTP_SS_CLOSING;
>                 ep = sctp_sk(sk)->ep;
>                 if (!list_empty(&ep->asocs)) {

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

* Re: net/sctp: null-ptr-deref in sctp_inet_listen
  2016-11-08 18:46   ` Andrey Konovalov
@ 2016-11-09  3:32     ` Xin Long
  2016-11-09 19:24       ` Andrey Konovalov
  0 siblings, 1 reply; 5+ messages in thread
From: Xin Long @ 2016-11-09  3:32 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp, netdev,
	LKML, Dmitry Vyukov, Alexander Potapenko, Kostya Serebryany,
	Eric Dumazet, syzkaller, Marcelo Ricardo Leitner

On Wed, Nov 9, 2016 at 2:46 AM, Andrey Konovalov <andreyknvl@google.com> wrote:
> Hi Xin,
>
> Your patch seems to be fixing the issue.
>
> Tested-by: Andrey Konovalov <andreyknvl@google.com>
>
> Thanks!
>
> On Tue, Nov 8, 2016 at 11:06 AM, Xin Long <lucien.xin@gmail.com> wrote:
>> On Tue, Nov 8, 2016 at 5:44 AM, Andrey Konovalov <andreyknvl@google.com> wrote:
>>> Hi,
>>>
>>> I've got the following error report while running the syzkaller fuzzer:
>>>
>>> kasan: CONFIG_KASAN_INLINE enabled
>>> kasan: GPF could be caused by NULL-ptr deref or user memory access
>>> general protection fault: 0000 [#1] SMP KASAN
>>> Modules linked in:
>>> CPU: 1 PID: 3851 Comm: a.out Not tainted 4.9.0-rc4+ #354
>>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>>> task: ffff880065f1d800 task.stack: ffff880063840000
>>> RIP: 0010:[<ffffffff8394151b>]  [<ffffffff8394151b>]
>>> sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
>>> RSP: 0018:ffff880063847dd0  EFLAGS: 00010202
>>> RAX: dffffc0000000000 RBX: 1ffff1000c708fbd RCX: 0000000000000000
>>> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
>>> RBP: ffff880063847e70 R08: dffffc0000000000 R09: dffffc0000000000
>>> R10: 0000000000000002 R11: 0000000000000002 R12: ffff88006b350800
>>> R13: 0000000000000000 R14: 1ffff1000d66a1a5 R15: 0000000000000000
>>> FS:  00007fd1f0f3d7c0(0000) GS:ffff88006cd00000(0000) knlGS:0000000000000000
>>> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>> CR2: 0000000020000000 CR3: 0000000064af9000 CR4: 00000000000006e0
>>> Stack:
>>>  ffff880063847de0 ffff880066165900 ffff88006b350d20 0000000041b58ab3
>>>  ffffffff847ff589 ffffffff83941280 dffffc0000000000 0000000000000000
>>>  ffff880069b9f740 0000000000000000 ffff880063847e38 ffffffff819f04ef
>>> Call Trace:
>>>  [<     inline     >] SYSC_listen net/socket.c:1396
>>>  [<ffffffff82b73cf6>] SyS_listen+0x206/0x250 net/socket.c:1382
>>>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>>> arch/x86/entry/entry_64.S:209
>>> Code: 00 0f 85 f4 04 00 00 4d 8b ac 24 28 05 00 00 49 b8 00 00 00 00
>>> 00 fc ff df 49 8d 7d 02 48 89 fe 49 89 fa 48 c1 ee 03 41 83 e2 07 <46>
>>> 0f b6 0c 06 41 83 c2 01 45 38 ca 7c 09 45 84 c9 0f 85 87 04
>>> RIP  [<ffffffff8394151b>] sctp_inet_listen+0x29b/0x790 net/sctp/socket.c:6870
>>>  RSP <ffff880063847dd0>
>>> ---[ end trace f2b501fc22999b37 ]---
>>>
>>> A reproducer is attached.
>>>
>>> On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).
>>>
>> This is a shutdown injection issue.
>> sctp_shutdown need a sk->state check, just like tcp_shutdown:
>>
>> --- a/net/sctp/socket.c
>> +++ b/net/sctp/socket.c
>> @@ -4287,7 +4287,8 @@ static void sctp_shutdown(struct sock *sk, int how)
>>         if (!sctp_style(sk, TCP))
>>                 return;
>>
>> -       if (how & SEND_SHUTDOWN) {
>> +       if (how & SEND_SHUTDOWN &&
>> +           (1 << sk->sk_state) & (SCTP_SS_ESTABLISHED | SCTP_SS_CLOSING)) {
>>                 sk->sk_state = SCTP_SS_CLOSING;
>>                 ep = sctp_sk(sk)->ep;
>>                 if (!list_empty(&ep->asocs)) {
this fix may break TYPE_SCTP_PRIMITIVE_SHUTDOWN statetable,
could you give the following one a try ? thanks.

--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4288,9 +4288,9 @@ static void sctp_shutdown(struct sock *sk, int how)
                return;

        if (how & SEND_SHUTDOWN) {
-               sk->sk_state = SCTP_SS_CLOSING;
                ep = sctp_sk(sk)->ep;
                if (!list_empty(&ep->asocs)) {
+                       sk->sk_state = SCTP_SS_CLOSING;
                        asoc = list_entry(ep->asocs.next,
                                          struct sctp_association, asocs);
                        sctp_primitive_SHUTDOWN(net, asoc, NULL);

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

* Re: net/sctp: null-ptr-deref in sctp_inet_listen
  2016-11-09  3:32     ` Xin Long
@ 2016-11-09 19:24       ` Andrey Konovalov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-09 19:24 UTC (permalink / raw)
  To: syzkaller
  Cc: Vlad Yasevich, Neil Horman, David S. Miller, linux-sctp, netdev,
	LKML, Dmitry Vyukov, Alexander Potapenko, Kostya Serebryany,
	Eric Dumazet, Marcelo Ricardo Leitner

On Wed, Nov 9, 2016 at 4:32 AM, Xin Long <lucien.xin@gmail.com> wrote:
> this fix may break TYPE_SCTP_PRIMITIVE_SHUTDOWN statetable,
> could you give the following one a try ? thanks.

This one also works.

Thanks.

>
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -4288,9 +4288,9 @@ static void sctp_shutdown(struct sock *sk, int how)
>                 return;
>
>         if (how & SEND_SHUTDOWN) {
> -               sk->sk_state = SCTP_SS_CLOSING;
>                 ep = sctp_sk(sk)->ep;
>                 if (!list_empty(&ep->asocs)) {
> +                       sk->sk_state = SCTP_SS_CLOSING;
>                         asoc = list_entry(ep->asocs.next,
>                                           struct sctp_association, asocs);
>                         sctp_primitive_SHUTDOWN(net, asoc, NULL);
>
> --
> 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+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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

end of thread, other threads:[~2016-11-09 19:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-07 21:44 net/sctp: null-ptr-deref in sctp_inet_listen Andrey Konovalov
2016-11-08 10:06 ` Xin Long
2016-11-08 18:46   ` Andrey Konovalov
2016-11-09  3:32     ` Xin Long
2016-11-09 19:24       ` Andrey Konovalov

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