linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* net/l2tp: use-after-free write in l2tp_ip6_close
@ 2016-11-07 22:35 Andrey Konovalov
  2016-11-07 23:02 ` Cong Wang
  2016-11-10 17:44 ` Guillaume Nault
  0 siblings, 2 replies; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-07 22:35 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Willem de Bruijn,
	Hannes Frederic Sowa, Soheil Hassas Yeganeh, Shmulik Ladkani,
	Wei Wang, Haishuang Yan, netdev, LKML
  Cc: Dmitry Vyukov, Kostya Serebryany, Alexander Potapenko, syzkaller

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

Hi,

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

==================================================================
BUG: KASAN: use-after-free in l2tp_ip6_close+0x239/0x2a0 at addr
ffff8800677276d8
Write of size 8 by task a.out/8668
CPU: 0 PID: 8668 Comm: a.out Not tainted 4.9.0-rc4+ #354
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
 ffff8800694d7b00 ffffffff81b46a64 ffff88006adb5780 ffff8800677276c0
 ffff880067727c68 ffff8800677276c0 ffff8800694d7b28 ffffffff8150a86c
 ffff8800694d7bb8 ffff88006adb5780 ffff8800e77276d8 ffff8800694d7ba8
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff81b46a64>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
 [<ffffffff8150a86c>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
 [<     inline     >] print_address_description mm/kasan/report.c:194
 [<ffffffff8150ab07>] kasan_report_error+0x1f7/0x4d0 mm/kasan/report.c:283
 [<     inline     >] kasan_report mm/kasan/report.c:303
 [<ffffffff8150b01e>] __asan_report_store8_noabort+0x3e/0x40
mm/kasan/report.c:329
 [<     inline     >] __write_once_size ./include/linux/compiler.h:272
 [<     inline     >] __hlist_del ./include/linux/list.h:622
 [<     inline     >] hlist_del_init ./include/linux/list.h:637
 [<ffffffff83825f49>] l2tp_ip6_close+0x239/0x2a0 net/l2tp/l2tp_ip6.c:239
 [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
 [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
 [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
 [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
 [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
 [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
 [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
 [<     inline     >] exit_task_work ./include/linux/task_work.h:21
 [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
 [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
 [<     inline     >] SYSC_exit_group kernel/exit.c:942
 [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
 [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
Object at ffff8800677276c0, in cache L2TP/IPv6 size: 1448
Allocated:
PID = 8692
[<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
[<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
[<     inline     >] set_track mm/kasan/kasan.c:507
[<ffffffff81509e4b>] kasan_kmalloc+0xab/0xe0 mm/kasan/kasan.c:598
[<ffffffff8150a3b2>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:537
[<     inline     >] slab_post_alloc_hook mm/slab.h:417
[<     inline     >] slab_alloc_node mm/slub.c:2708
[<     inline     >] slab_alloc mm/slub.c:2716
[<ffffffff81505064>] kmem_cache_alloc+0xb4/0x270 mm/slub.c:2721
[<ffffffff82b77ca9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1327
[<ffffffff82b80898>] sk_alloc+0x38/0xaf0 net/core/sock.c:1389
[<ffffffff832cef05>] inet6_create+0x2e5/0xf60 net/ipv6/af_inet6.c:182
[<ffffffff82b7301f>] __sock_create+0x37f/0x640 net/socket.c:1153
[<     inline     >] sock_create net/socket.c:1193
[<     inline     >] SYSC_socket net/socket.c:1223
[<ffffffff82b73510>] SyS_socket+0xf0/0x1b0 net/socket.c:1203
[<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
Freed:
PID = 8668
[<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
[<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
[<     inline     >] set_track mm/kasan/kasan.c:507
[<ffffffff8150a433>] kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:571
[<     inline     >] slab_free_hook mm/slub.c:1352
[<     inline     >] slab_free_freelist_hook mm/slub.c:1374
[<     inline     >] slab_free mm/slub.c:2951
[<ffffffff81506263>] kmem_cache_free+0xb3/0x2c0 mm/slub.c:2973
[<     inline     >] sk_prot_free net/core/sock.c:1370
[<ffffffff82b7c669>] __sk_destruct+0x319/0x480 net/core/sock.c:1445
[<ffffffff82b82b94>] sk_destruct+0x44/0x80 net/core/sock.c:1453
[<ffffffff82b82c24>] __sk_free+0x54/0x230 net/core/sock.c:1461
[<ffffffff82b82e23>] sk_free+0x23/0x30 net/core/sock.c:1472
[<     inline     >] sock_put ./include/net/sock.h:1591
[<ffffffff82b84b04>] sk_common_release+0x294/0x3e0 net/core/sock.c:2745
[<ffffffff83825f19>] l2tp_ip6_close+0x209/0x2a0 net/l2tp/l2tp_ip6.c:243
[<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
[<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
[<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
[<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
[<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
[<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
[<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
[<     inline     >] exit_task_work ./include/linux/task_work.h:21
[<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
[<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
[<     inline     >] SYSC_exit_group kernel/exit.c:942
[<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
[<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
Memory state around the buggy address:
 ffff880067727580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff880067727600: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc
>ffff880067727680: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
                                                    ^
 ffff880067727700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff880067727780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

To reproduce run the attached program in a tight parallel loop using
stress (https://godoc.org/golang.org/x/tools/cmd/stress):
$ gcc -lpthread tmp.c
$ ./stress ./a.out

On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).

Thanks!

[-- Attachment #2: l2tp-uaf-poc.c --]
[-- Type: application/octet-stream, Size: 8669 bytes --]

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

#ifndef __NR_bind
#define __NR_bind 49
#endif
#ifndef __NR_syz_fuseblk_mount
#define __NR_syz_fuseblk_mount 1000005
#endif
#ifndef __NR_syz_open_pts
#define __NR_syz_open_pts 1000003
#endif
#ifndef __NR_socket
#define __NR_socket 41
#endif
#ifndef __NR_syz_fuse_mount
#define __NR_syz_fuse_mount 1000004
#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_mmap
#define __NR_mmap 9
#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[10];
void* thr(void* arg)
{
  switch ((long)arg) {
  case 0:
    r[0] =
        execute_syscall(__NR_mmap, 0x20000000ul, 0xecf000ul, 0x3ul,
                        0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
    break;
  case 1:
    r[1] = execute_syscall(__NR_socket, 0x0ul, 0x0ul, 0x0ul, 0, 0, 0, 0,
                           0, 0);
    break;
  case 2:
    NONFAILING(memcpy(
        (void*)0x202e2f80,
        "\x0a\x00\x42\x42\x7c\xd2\xe1\x9f\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x8c\x54\x2f\x33\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00",
        128));
    r[3] = execute_syscall(__NR_bind, r[1], 0x202e2f80ul, 0x80ul, 0, 0,
                           0, 0, 0, 0);
    break;
  case 3:
    r[4] = execute_syscall(__NR_socket, 0xaul, 0x2ul, 0x73ul, 0, 0, 0,
                           0, 0, 0);
    break;
  case 4:
    r[5] =
        execute_syscall(__NR_mmap, 0x20ecf000ul, 0x1000ul, 0x3ul,
                        0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
    break;
  case 5:
    NONFAILING(memcpy(
        (void*)0x20ecf000,
        "\x0a\x00\x42\x42\x25\x93\x9f\xe4\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x90\x0d\x0e\x38\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00",
        128));
    r[7] = execute_syscall(__NR_bind, r[4], 0x20ecf000ul, 0x80ul, 0, 0,
                           0, 0, 0, 0);
    break;
  case 6:
    NONFAILING(memcpy(
        (void*)0x20ec6000,
        "\x0a\x00\x42\x42\x7c\xd2\xe1\x9f\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x8c\x54\x2f\x33\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
        "\x00\x00\x00\x00\x00\x00\x00\x00",
        128));
    r[9] = execute_syscall(__NR_bind, r[4], 0x20ec6000ul, 0x80ul, 0, 0,
                           0, 0, 0, 0);
    break;
  }
  return 0;
}

int main()
{
  long i;
  pthread_t th[14];

  install_segv_handler();
  memset(r, -1, sizeof(r));
  srand(getpid());
  for (i = 0; i < 7; i++) {
    pthread_create(&th[i], 0, thr, (void*)i);
    usleep(10000);
  }
  for (i = 0; i < 7; i++) {
    pthread_create(&th[7 + i], 0, thr, (void*)i);
    if (rand() % 2)
      usleep(rand() % 10000);
  }
  usleep(100000);
  return 0;
}

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

* Re: net/l2tp: use-after-free write in l2tp_ip6_close
  2016-11-07 22:35 net/l2tp: use-after-free write in l2tp_ip6_close Andrey Konovalov
@ 2016-11-07 23:02 ` Cong Wang
  2016-11-08 19:45   ` Andrey Konovalov
  2016-11-10 17:44 ` Guillaume Nault
  1 sibling, 1 reply; 5+ messages in thread
From: Cong Wang @ 2016-11-07 23:02 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: David S. Miller, Eric Dumazet, Willem de Bruijn,
	Hannes Frederic Sowa, Soheil Hassas Yeganeh, Shmulik Ladkani,
	Wei Wang, Haishuang Yan, netdev, LKML, Dmitry Vyukov,
	Kostya Serebryany, Alexander Potapenko, syzkaller

On Mon, Nov 7, 2016 at 2:35 PM, Andrey Konovalov <andreyknvl@google.com> wrote:
> Hi,
>
> I've got the following error report while running the syzkaller fuzzer:
>
> ==================================================================
> BUG: KASAN: use-after-free in l2tp_ip6_close+0x239/0x2a0 at addr
> ffff8800677276d8
> Write of size 8 by task a.out/8668
> CPU: 0 PID: 8668 Comm: a.out Not tainted 4.9.0-rc4+ #354
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>  ffff8800694d7b00 ffffffff81b46a64 ffff88006adb5780 ffff8800677276c0
>  ffff880067727c68 ffff8800677276c0 ffff8800694d7b28 ffffffff8150a86c
>  ffff8800694d7bb8 ffff88006adb5780 ffff8800e77276d8 ffff8800694d7ba8
> Call Trace:
>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>  [<ffffffff81b46a64>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
>  [<ffffffff8150a86c>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>  [<     inline     >] print_address_description mm/kasan/report.c:194
>  [<ffffffff8150ab07>] kasan_report_error+0x1f7/0x4d0 mm/kasan/report.c:283
>  [<     inline     >] kasan_report mm/kasan/report.c:303
>  [<ffffffff8150b01e>] __asan_report_store8_noabort+0x3e/0x40
> mm/kasan/report.c:329
>  [<     inline     >] __write_once_size ./include/linux/compiler.h:272
>  [<     inline     >] __hlist_del ./include/linux/list.h:622
>  [<     inline     >] hlist_del_init ./include/linux/list.h:637
>  [<ffffffff83825f49>] l2tp_ip6_close+0x239/0x2a0 net/l2tp/l2tp_ip6.c:239
>  [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
>  [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>  [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
>  [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
>  [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
>  [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
>  [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
>  [<     inline     >] exit_task_work ./include/linux/task_work.h:21
>  [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
>  [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
>  [<     inline     >] SYSC_exit_group kernel/exit.c:942
>  [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209

I guess we need to lock the sock for l2tp_ip6_disconnect() too.

diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index ad3468c..ea2ae66 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -410,7 +410,7 @@ static int l2tp_ip6_disconnect(struct sock *sk, int flags)
        if (sock_flag(sk, SOCK_ZAPPED))
                return 0;

-       return __udp_disconnect(sk, flags);
+       return udp_disconnect(sk, flags);
 }

 static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,

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

* Re: net/l2tp: use-after-free write in l2tp_ip6_close
  2016-11-07 23:02 ` Cong Wang
@ 2016-11-08 19:45   ` Andrey Konovalov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-08 19:45 UTC (permalink / raw)
  To: syzkaller
  Cc: David S. Miller, Eric Dumazet, Willem de Bruijn,
	Hannes Frederic Sowa, Soheil Hassas Yeganeh, Shmulik Ladkani,
	Wei Wang, Haishuang Yan, netdev, LKML, Dmitry Vyukov,
	Kostya Serebryany, Alexander Potapenko

Hi Cong,

Tried with your patch, still seeing the reports.

Thanks!

On Tue, Nov 8, 2016 at 12:02 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Mon, Nov 7, 2016 at 2:35 PM, Andrey Konovalov <andreyknvl@google.com> wrote:
>> Hi,
>>
>> I've got the following error report while running the syzkaller fuzzer:
>>
>> ==================================================================
>> BUG: KASAN: use-after-free in l2tp_ip6_close+0x239/0x2a0 at addr
>> ffff8800677276d8
>> Write of size 8 by task a.out/8668
>> CPU: 0 PID: 8668 Comm: a.out Not tainted 4.9.0-rc4+ #354
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>>  ffff8800694d7b00 ffffffff81b46a64 ffff88006adb5780 ffff8800677276c0
>>  ffff880067727c68 ffff8800677276c0 ffff8800694d7b28 ffffffff8150a86c
>>  ffff8800694d7bb8 ffff88006adb5780 ffff8800e77276d8 ffff8800694d7ba8
>> Call Trace:
>>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>>  [<ffffffff81b46a64>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
>>  [<ffffffff8150a86c>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>>  [<     inline     >] print_address_description mm/kasan/report.c:194
>>  [<ffffffff8150ab07>] kasan_report_error+0x1f7/0x4d0 mm/kasan/report.c:283
>>  [<     inline     >] kasan_report mm/kasan/report.c:303
>>  [<ffffffff8150b01e>] __asan_report_store8_noabort+0x3e/0x40
>> mm/kasan/report.c:329
>>  [<     inline     >] __write_once_size ./include/linux/compiler.h:272
>>  [<     inline     >] __hlist_del ./include/linux/list.h:622
>>  [<     inline     >] hlist_del_init ./include/linux/list.h:637
>>  [<ffffffff83825f49>] l2tp_ip6_close+0x239/0x2a0 net/l2tp/l2tp_ip6.c:239
>>  [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
>>  [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>>  [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
>>  [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
>>  [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
>>  [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
>>  [<     inline     >] exit_task_work ./include/linux/task_work.h:21
>>  [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
>>  [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
>>  [<     inline     >] SYSC_exit_group kernel/exit.c:942
>>  [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
>>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>
> I guess we need to lock the sock for l2tp_ip6_disconnect() too.
>
> diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
> index ad3468c..ea2ae66 100644
> --- a/net/l2tp/l2tp_ip6.c
> +++ b/net/l2tp/l2tp_ip6.c
> @@ -410,7 +410,7 @@ static int l2tp_ip6_disconnect(struct sock *sk, int flags)
>         if (sock_flag(sk, SOCK_ZAPPED))
>                 return 0;
>
> -       return __udp_disconnect(sk, flags);
> +       return udp_disconnect(sk, flags);
>  }
>
>  static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr,
>
> --
> 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

* Re: net/l2tp: use-after-free write in l2tp_ip6_close
  2016-11-07 22:35 net/l2tp: use-after-free write in l2tp_ip6_close Andrey Konovalov
  2016-11-07 23:02 ` Cong Wang
@ 2016-11-10 17:44 ` Guillaume Nault
  2016-11-22  9:23   ` Andrey Konovalov
  1 sibling, 1 reply; 5+ messages in thread
From: Guillaume Nault @ 2016-11-10 17:44 UTC (permalink / raw)
  To: Andrey Konovalov
  Cc: David S. Miller, Eric Dumazet, Willem de Bruijn,
	Hannes Frederic Sowa, Soheil Hassas Yeganeh, Shmulik Ladkani,
	Wei Wang, Haishuang Yan, netdev, LKML, Dmitry Vyukov,
	Kostya Serebryany, Alexander Potapenko, syzkaller

On Mon, Nov 07, 2016 at 11:35:26PM +0100, Andrey Konovalov wrote:
> Hi,
> 
> I've got the following error report while running the syzkaller fuzzer:
> 
> ==================================================================
> BUG: KASAN: use-after-free in l2tp_ip6_close+0x239/0x2a0 at addr
> ffff8800677276d8
> Write of size 8 by task a.out/8668
> CPU: 0 PID: 8668 Comm: a.out Not tainted 4.9.0-rc4+ #354
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>  ffff8800694d7b00 ffffffff81b46a64 ffff88006adb5780 ffff8800677276c0
>  ffff880067727c68 ffff8800677276c0 ffff8800694d7b28 ffffffff8150a86c
>  ffff8800694d7bb8 ffff88006adb5780 ffff8800e77276d8 ffff8800694d7ba8
> Call Trace:
>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>  [<ffffffff81b46a64>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
>  [<ffffffff8150a86c>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>  [<     inline     >] print_address_description mm/kasan/report.c:194
>  [<ffffffff8150ab07>] kasan_report_error+0x1f7/0x4d0 mm/kasan/report.c:283
>  [<     inline     >] kasan_report mm/kasan/report.c:303
>  [<ffffffff8150b01e>] __asan_report_store8_noabort+0x3e/0x40
> mm/kasan/report.c:329
>  [<     inline     >] __write_once_size ./include/linux/compiler.h:272
>  [<     inline     >] __hlist_del ./include/linux/list.h:622
>  [<     inline     >] hlist_del_init ./include/linux/list.h:637
>  [<ffffffff83825f49>] l2tp_ip6_close+0x239/0x2a0 net/l2tp/l2tp_ip6.c:239
>  [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
>  [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>  [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
>  [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
>  [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
>  [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
>  [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
>  [<     inline     >] exit_task_work ./include/linux/task_work.h:21
>  [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
>  [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
>  [<     inline     >] SYSC_exit_group kernel/exit.c:942
>  [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> Object at ffff8800677276c0, in cache L2TP/IPv6 size: 1448
> Allocated:
> PID = 8692
> [<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
> [<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
> [<     inline     >] set_track mm/kasan/kasan.c:507
> [<ffffffff81509e4b>] kasan_kmalloc+0xab/0xe0 mm/kasan/kasan.c:598
> [<ffffffff8150a3b2>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:537
> [<     inline     >] slab_post_alloc_hook mm/slab.h:417
> [<     inline     >] slab_alloc_node mm/slub.c:2708
> [<     inline     >] slab_alloc mm/slub.c:2716
> [<ffffffff81505064>] kmem_cache_alloc+0xb4/0x270 mm/slub.c:2721
> [<ffffffff82b77ca9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1327
> [<ffffffff82b80898>] sk_alloc+0x38/0xaf0 net/core/sock.c:1389
> [<ffffffff832cef05>] inet6_create+0x2e5/0xf60 net/ipv6/af_inet6.c:182
> [<ffffffff82b7301f>] __sock_create+0x37f/0x640 net/socket.c:1153
> [<     inline     >] sock_create net/socket.c:1193
> [<     inline     >] SYSC_socket net/socket.c:1223
> [<ffffffff82b73510>] SyS_socket+0xf0/0x1b0 net/socket.c:1203
> [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> Freed:
> PID = 8668
> [<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
> [<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
> [<     inline     >] set_track mm/kasan/kasan.c:507
> [<ffffffff8150a433>] kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:571
> [<     inline     >] slab_free_hook mm/slub.c:1352
> [<     inline     >] slab_free_freelist_hook mm/slub.c:1374
> [<     inline     >] slab_free mm/slub.c:2951
> [<ffffffff81506263>] kmem_cache_free+0xb3/0x2c0 mm/slub.c:2973
> [<     inline     >] sk_prot_free net/core/sock.c:1370
> [<ffffffff82b7c669>] __sk_destruct+0x319/0x480 net/core/sock.c:1445
> [<ffffffff82b82b94>] sk_destruct+0x44/0x80 net/core/sock.c:1453
> [<ffffffff82b82c24>] __sk_free+0x54/0x230 net/core/sock.c:1461
> [<ffffffff82b82e23>] sk_free+0x23/0x30 net/core/sock.c:1472
> [<     inline     >] sock_put ./include/net/sock.h:1591
> [<ffffffff82b84b04>] sk_common_release+0x294/0x3e0 net/core/sock.c:2745
> [<ffffffff83825f19>] l2tp_ip6_close+0x209/0x2a0 net/l2tp/l2tp_ip6.c:243
> [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
> [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
> [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
> [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
> [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
> [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
> [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
> [<     inline     >] exit_task_work ./include/linux/task_work.h:21
> [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
> [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
> [<     inline     >] SYSC_exit_group kernel/exit.c:942
> [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
> [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> Memory state around the buggy address:
>  ffff880067727580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff880067727600: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc
> >ffff880067727680: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>                                                     ^
>  ffff880067727700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff880067727780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
> 
> To reproduce run the attached program in a tight parallel loop using
> stress (https://godoc.org/golang.org/x/tools/cmd/stress):
> $ gcc -lpthread tmp.c
> $ ./stress ./a.out
> 
> On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).
> 

Thanks for the report. It looks like l2tp_ip6_bind() is racy.
Can you try the following patch?

diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index ad3468c..9978d01 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -269,8 +269,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        int addr_type;
        int err;

-       if (!sock_flag(sk, SOCK_ZAPPED))
-               return -EINVAL;
        if (addr->l2tp_family != AF_INET6)
                return -EINVAL;
        if (addr_len < sizeof(*addr))
@@ -296,6 +294,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        lock_sock(sk);

        err = -EINVAL;
+       if (!sock_flag(sk, SOCK_ZAPPED))
+               goto out_unlock;
+
        if (sk->sk_state != TCP_CLOSE)
                goto out_unlock;

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

* Re: net/l2tp: use-after-free write in l2tp_ip6_close
  2016-11-10 17:44 ` Guillaume Nault
@ 2016-11-22  9:23   ` Andrey Konovalov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Konovalov @ 2016-11-22  9:23 UTC (permalink / raw)
  To: Guillaume Nault
  Cc: David S. Miller, Eric Dumazet, Willem de Bruijn,
	Hannes Frederic Sowa, Soheil Hassas Yeganeh, Shmulik Ladkani,
	Wei Wang, Haishuang Yan, netdev, LKML, Dmitry Vyukov,
	Kostya Serebryany, Alexander Potapenko, syzkaller

Hi Guillaume,

Sorry, I was on vacation last week, couldn't reply.

As I can see a fix was already sent upstream.

Thanks!

On Thu, Nov 10, 2016 at 6:44 PM, Guillaume Nault <g.nault@alphalink.fr> wrote:
> On Mon, Nov 07, 2016 at 11:35:26PM +0100, Andrey Konovalov wrote:
>> Hi,
>>
>> I've got the following error report while running the syzkaller fuzzer:
>>
>> ==================================================================
>> BUG: KASAN: use-after-free in l2tp_ip6_close+0x239/0x2a0 at addr
>> ffff8800677276d8
>> Write of size 8 by task a.out/8668
>> CPU: 0 PID: 8668 Comm: a.out Not tainted 4.9.0-rc4+ #354
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>>  ffff8800694d7b00 ffffffff81b46a64 ffff88006adb5780 ffff8800677276c0
>>  ffff880067727c68 ffff8800677276c0 ffff8800694d7b28 ffffffff8150a86c
>>  ffff8800694d7bb8 ffff88006adb5780 ffff8800e77276d8 ffff8800694d7ba8
>> Call Trace:
>>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>>  [<ffffffff81b46a64>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
>>  [<ffffffff8150a86c>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>>  [<     inline     >] print_address_description mm/kasan/report.c:194
>>  [<ffffffff8150ab07>] kasan_report_error+0x1f7/0x4d0 mm/kasan/report.c:283
>>  [<     inline     >] kasan_report mm/kasan/report.c:303
>>  [<ffffffff8150b01e>] __asan_report_store8_noabort+0x3e/0x40
>> mm/kasan/report.c:329
>>  [<     inline     >] __write_once_size ./include/linux/compiler.h:272
>>  [<     inline     >] __hlist_del ./include/linux/list.h:622
>>  [<     inline     >] hlist_del_init ./include/linux/list.h:637
>>  [<ffffffff83825f49>] l2tp_ip6_close+0x239/0x2a0 net/l2tp/l2tp_ip6.c:239
>>  [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
>>  [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>>  [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
>>  [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
>>  [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
>>  [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
>>  [<     inline     >] exit_task_work ./include/linux/task_work.h:21
>>  [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
>>  [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
>>  [<     inline     >] SYSC_exit_group kernel/exit.c:942
>>  [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
>>  [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>> Object at ffff8800677276c0, in cache L2TP/IPv6 size: 1448
>> Allocated:
>> PID = 8692
>> [<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
>> [<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
>> [<     inline     >] set_track mm/kasan/kasan.c:507
>> [<ffffffff81509e4b>] kasan_kmalloc+0xab/0xe0 mm/kasan/kasan.c:598
>> [<ffffffff8150a3b2>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:537
>> [<     inline     >] slab_post_alloc_hook mm/slab.h:417
>> [<     inline     >] slab_alloc_node mm/slub.c:2708
>> [<     inline     >] slab_alloc mm/slub.c:2716
>> [<ffffffff81505064>] kmem_cache_alloc+0xb4/0x270 mm/slub.c:2721
>> [<ffffffff82b77ca9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1327
>> [<ffffffff82b80898>] sk_alloc+0x38/0xaf0 net/core/sock.c:1389
>> [<ffffffff832cef05>] inet6_create+0x2e5/0xf60 net/ipv6/af_inet6.c:182
>> [<ffffffff82b7301f>] __sock_create+0x37f/0x640 net/socket.c:1153
>> [<     inline     >] sock_create net/socket.c:1193
>> [<     inline     >] SYSC_socket net/socket.c:1223
>> [<ffffffff82b73510>] SyS_socket+0xf0/0x1b0 net/socket.c:1203
>> [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>> Freed:
>> PID = 8668
>> [<ffffffff8107e236>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
>> [<ffffffff81509bd6>] save_stack+0x46/0xd0 mm/kasan/kasan.c:495
>> [<     inline     >] set_track mm/kasan/kasan.c:507
>> [<ffffffff8150a433>] kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:571
>> [<     inline     >] slab_free_hook mm/slub.c:1352
>> [<     inline     >] slab_free_freelist_hook mm/slub.c:1374
>> [<     inline     >] slab_free mm/slub.c:2951
>> [<ffffffff81506263>] kmem_cache_free+0xb3/0x2c0 mm/slub.c:2973
>> [<     inline     >] sk_prot_free net/core/sock.c:1370
>> [<ffffffff82b7c669>] __sk_destruct+0x319/0x480 net/core/sock.c:1445
>> [<ffffffff82b82b94>] sk_destruct+0x44/0x80 net/core/sock.c:1453
>> [<ffffffff82b82c24>] __sk_free+0x54/0x230 net/core/sock.c:1461
>> [<ffffffff82b82e23>] sk_free+0x23/0x30 net/core/sock.c:1472
>> [<     inline     >] sock_put ./include/net/sock.h:1591
>> [<ffffffff82b84b04>] sk_common_release+0x294/0x3e0 net/core/sock.c:2745
>> [<ffffffff83825f19>] l2tp_ip6_close+0x209/0x2a0 net/l2tp/l2tp_ip6.c:243
>> [<ffffffff8316b31f>] inet_release+0xef/0x1c0 net/ipv4/af_inet.c:415
>> [<ffffffff832cd4d0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>> [<ffffffff82b6d89e>] sock_release+0x8e/0x1d0 net/socket.c:570
>> [<ffffffff82b6d9f6>] sock_close+0x16/0x20 net/socket.c:1017
>> [<ffffffff81524bdd>] __fput+0x29d/0x720 fs/file_table.c:208
>> [<ffffffff815250e5>] ____fput+0x15/0x20 fs/file_table.c:244
>> [<ffffffff81172928>] task_work_run+0xf8/0x170 kernel/task_work.c:116
>> [<     inline     >] exit_task_work ./include/linux/task_work.h:21
>> [<ffffffff8111bda3>] do_exit+0x883/0x2ac0 kernel/exit.c:828
>> [<ffffffff8112234e>] do_group_exit+0x10e/0x340 kernel/exit.c:931
>> [<     inline     >] SYSC_exit_group kernel/exit.c:942
>> [<ffffffff8112259d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:940
>> [<ffffffff83fc1501>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>> Memory state around the buggy address:
>>  ffff880067727580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>  ffff880067727600: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc
>> >ffff880067727680: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>>                                                     ^
>>  ffff880067727700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>  ffff880067727780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>> ==================================================================
>>
>> To reproduce run the attached program in a tight parallel loop using
>> stress (https://godoc.org/golang.org/x/tools/cmd/stress):
>> $ gcc -lpthread tmp.c
>> $ ./stress ./a.out
>>
>> On commit bc33b0ca11e3df467777a4fa7639ba488c9d4911 (Nov 5).
>>
>
> Thanks for the report. It looks like l2tp_ip6_bind() is racy.
> Can you try the following patch?
>
> diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
> index ad3468c..9978d01 100644
> --- a/net/l2tp/l2tp_ip6.c
> +++ b/net/l2tp/l2tp_ip6.c
> @@ -269,8 +269,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>         int addr_type;
>         int err;
>
> -       if (!sock_flag(sk, SOCK_ZAPPED))
> -               return -EINVAL;
>         if (addr->l2tp_family != AF_INET6)
>                 return -EINVAL;
>         if (addr_len < sizeof(*addr))
> @@ -296,6 +294,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
>         lock_sock(sk);
>
>         err = -EINVAL;
> +       if (!sock_flag(sk, SOCK_ZAPPED))
> +               goto out_unlock;
> +
>         if (sk->sk_state != TCP_CLOSE)
>                 goto out_unlock;

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

end of thread, other threads:[~2016-11-22  9:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-07 22:35 net/l2tp: use-after-free write in l2tp_ip6_close Andrey Konovalov
2016-11-07 23:02 ` Cong Wang
2016-11-08 19:45   ` Andrey Konovalov
2016-11-10 17:44 ` Guillaume Nault
2016-11-22  9:23   ` 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).