04 Sep, 2020

1 commit

  • The l2tp tunnel and session structures contain a "magic feather" field
    which was originally intended to help trace lifetime bugs in the code.

    Since the introduction of the shared kernel refcount code in refcount.h,
    and l2tp's porting to those APIs, we are covered by the refcount code's
    checks and warnings. Duplicating those checks in the l2tp code isn't
    useful.

    However, magic feather checks are still useful to help to detect bugs
    stemming from misuse/trampling of the sk_user_data pointer in struct
    sock. The l2tp code makes extensive use of sk_user_data to stash
    pointers to the tunnel and session structures, and if another subsystem
    overwrites sk_user_data it's important to detect this.

    As such, rework l2tp's magic feather checks to focus on validating the
    tunnel and session data structures when they're extracted from
    sk_user_data.

    * Add a new accessor function l2tp_sk_to_tunnel which contains a magic
    feather check, and is used by l2tp_core and l2tp_ip[6]
    * Comment l2tp_udp_encap_recv which doesn't use this new accessor function
    because of the specific nature of the codepath it is called in
    * Drop l2tp_session_queue_purge's check on the session magic feather:
    it is called from code which is walking the tunnel session list, and
    hence doesn't need validation
    * Drop l2tp_session_free's check on the tunnel magic feather: the
    intention of this check is covered by refcount.h's reference count
    sanity checking
    * Add session magic validation in pppol2tp_ioctl. On failure return
    -EBADF, which mirrors the approach in pppol2tp_[sg]etsockopt.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     

23 Aug, 2020

1 commit

  • l2tp had logging to trace data frame receipt and transmission, including
    code to dump packet contents. This was originally intended to aid
    debugging of core l2tp packet handling, but is of limited use now that
    code is stable.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     

31 Jul, 2020

1 commit

  • All of the l2tp subsystem's exported symbols are exported using
    EXPORT_SYMBOL_GPL, except for l2tp_recv_common and l2tp_ioctl.

    These functions alone are not useful without the rest of the l2tp
    infrastructure, so there's no practical benefit to these symbols using a
    different export policy.

    Change these exports to use EXPORT_SYMBOL_GPL for consistency with the
    rest of l2tp.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     

25 Jul, 2020

1 commit


24 Jul, 2020

1 commit

  • checkpatch warns about comparisons to NULL, e.g.

    CHECK: Comparison to NULL could be written "!rt"
    #474: FILE: net/l2tp/l2tp_ip.c:474:
    + if (rt == NULL) {

    These sort of comparisons are generally clearer and more readable
    the way checkpatch suggests, so update l2tp accordingly.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     

23 Jul, 2020

2 commits

  • Modify some l2tp comments to better adhere to kernel coding style, as
    reported by checkpatch.pl.

    Add descriptive comments for the l2tp per-net spinlocks to document
    their use.

    Fix an incorrect comment in l2tp_recv_common:

    RFC2661 section 5.4 states that:

    "The LNS controls enabling and disabling of sequence numbers by sending a
    data message with or without sequence numbers present at any time during
    the life of a session."

    l2tp handles this correctly in l2tp_recv_common, but the comment around
    the code was incorrect and confusing. Fix up the comment accordingly.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     
  • Fix up various whitespace issues as reported by checkpatch.pl:

    * remove spaces around operators where appropriate,
    * add missing blank lines following declarations,
    * remove multiple blank lines, or trailing blank lines at the end of
    functions.

    Signed-off-by: Tom Parkin
    Signed-off-by: David S. Miller

    Tom Parkin
     

20 Jul, 2020

2 commits


31 May, 2020

1 commit

  • syzbot recently found a way to crash the kernel [1]

    Issue here is that inet_hash() & inet_unhash() are currently
    only meant to be used by TCP & DCCP, since only these protocols
    provide the needed hashinfo pointer.

    L2TP uses a single list (instead of a hash table)

    This old bug became an issue after commit 610236587600
    ("bpf: Add new cgroup attach type to enable sock modifications")
    since after this commit, sk_common_release() can be called
    while the L2TP socket is still considered 'hashed'.

    general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN
    KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
    CPU: 0 PID: 7063 Comm: syz-executor654 Not tainted 5.7.0-rc6-syzkaller #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    RIP: 0010:inet_unhash+0x11f/0x770 net/ipv4/inet_hashtables.c:600
    Code: 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e dd 04 00 00 48 8d 7d 08 44 8b 73 08 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 3c 02 00 0f 85 55 05 00 00 48 8d 7d 14 4c 8b 6d 08 48 b8 00 00
    RSP: 0018:ffffc90001777d30 EFLAGS: 00010202
    RAX: dffffc0000000000 RBX: ffff88809a6df940 RCX: ffffffff8697c242
    RDX: 0000000000000001 RSI: ffffffff8697c251 RDI: 0000000000000008
    RBP: 0000000000000000 R08: ffff88809f3ae1c0 R09: fffffbfff1514cc1
    R10: ffffffff8a8a6607 R11: fffffbfff1514cc0 R12: ffff88809a6df9b0
    R13: 0000000000000007 R14: 0000000000000000 R15: ffffffff873a4d00
    FS: 0000000001d2b880(0000) GS:ffff8880ae600000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00000000006cd090 CR3: 000000009403a000 CR4: 00000000001406f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
    sk_common_release+0xba/0x370 net/core/sock.c:3210
    inet_create net/ipv4/af_inet.c:390 [inline]
    inet_create+0x966/0xe00 net/ipv4/af_inet.c:248
    __sock_create+0x3cb/0x730 net/socket.c:1428
    sock_create net/socket.c:1479 [inline]
    __sys_socket+0xef/0x200 net/socket.c:1521
    __do_sys_socket net/socket.c:1530 [inline]
    __se_sys_socket net/socket.c:1528 [inline]
    __x64_sys_socket+0x6f/0xb0 net/socket.c:1528
    do_syscall_64+0xf6/0x7d0 arch/x86/entry/common.c:295
    entry_SYSCALL_64_after_hwframe+0x49/0xb3
    RIP: 0033:0x441e29
    Code: e8 fc b3 02 00 48 83 c4 18 c3 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 3d 01 f0 ff ff 0f 83 eb 08 fc ff c3 66 2e 0f 1f 84 00 00 00 00
    RSP: 002b:00007ffdce184148 EFLAGS: 00000246 ORIG_RAX: 0000000000000029
    RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000441e29
    RDX: 0000000000000073 RSI: 0000000000000002 RDI: 0000000000000002
    RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
    R13: 0000000000402c30 R14: 0000000000000000 R15: 0000000000000000
    Modules linked in:
    ---[ end trace 23b6578228ce553e ]---
    RIP: 0010:inet_unhash+0x11f/0x770 net/ipv4/inet_hashtables.c:600
    Code: 03 0f b6 04 02 84 c0 74 08 3c 03 0f 8e dd 04 00 00 48 8d 7d 08 44 8b 73 08 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 3c 02 00 0f 85 55 05 00 00 48 8d 7d 14 4c 8b 6d 08 48 b8 00 00
    RSP: 0018:ffffc90001777d30 EFLAGS: 00010202
    RAX: dffffc0000000000 RBX: ffff88809a6df940 RCX: ffffffff8697c242
    RDX: 0000000000000001 RSI: ffffffff8697c251 RDI: 0000000000000008
    RBP: 0000000000000000 R08: ffff88809f3ae1c0 R09: fffffbfff1514cc1
    R10: ffffffff8a8a6607 R11: fffffbfff1514cc0 R12: ffff88809a6df9b0
    R13: 0000000000000007 R14: 0000000000000000 R15: ffffffff873a4d00
    FS: 0000000001d2b880(0000) GS:ffff8880ae600000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00000000006cd090 CR3: 000000009403a000 CR4: 00000000001406f0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

    Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support")
    Signed-off-by: Eric Dumazet
    Cc: James Chapman
    Cc: Andrii Nakryiko
    Reported-by: syzbot+3610d489778b57cc8031@syzkaller.appspotmail.com

    Eric Dumazet
     

02 Oct, 2019

1 commit

  • commit 174e23810cd31
    ("sk_buff: drop all skb extensions on free and skb scrubbing") made napi
    recycle always drop skb extensions. The additional skb_ext_del() that is
    performed via nf_reset on napi skb recycle is not needed anymore.

    Most nf_reset() calls in the stack are there so queued skb won't block
    'rmmod nf_conntrack' indefinitely.

    This removes the skb_ext_del from nf_reset, and renames it to a more
    fitting nf_reset_ct().

    In a few selected places, add a call to skb_ext_reset to make sure that
    no active extensions remain.

    I am submitting this for "net", because we're still early in the release
    cycle. The patch applies to net-next too, but I think the rename causes
    needless divergence between those trees.

    Suggested-by: Eric Dumazet
    Signed-off-by: Florian Westphal
    Signed-off-by: Pablo Neira Ayuso

    Florian Westphal
     

31 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 3029 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

20 Apr, 2019

1 commit

  • The SIOCGSTAMP/SIOCGSTAMPNS ioctl commands are implemented by many
    socket protocol handlers, and all of those end up calling the same
    sock_get_timestamp()/sock_get_timestampns() helper functions, which
    results in a lot of duplicate code.

    With the introduction of 64-bit time_t on 32-bit architectures, this
    gets worse, as we then need four different ioctl commands in each
    socket protocol implementation.

    To simplify that, let's add a new .gettstamp() operation in
    struct proto_ops, and move ioctl implementation into the common
    sock_ioctl()/compat_sock_ioctl_trans() functions that these all go
    through.

    We can reuse the sock_get_timestamp() implementation, but generalize
    it so it can deal with both native and compat mode, as well as
    timeval and timespec structures.

    Acked-by: Stefan Schmidt
    Acked-by: Neil Horman
    Acked-by: Marc Kleine-Budde
    Link: https://lore.kernel.org/lkml/CAK8P3a038aDQQotzua_QtKGhq8O9n+rdiz2=WDCp82ys8eUT+A@mail.gmail.com/
    Signed-off-by: Arnd Bergmann
    Acked-by: Willem de Bruijn
    Signed-off-by: David S. Miller

    Arnd Bergmann
     

31 Jan, 2019

1 commit

  • Use pskb_may_pull() to make sure the optional fields are in skb linear
    parts, so we can safely read them later.

    It's easy to reproduce the issue with a net driver that supports paged
    skb data. Just create a L2TPv3 over IP tunnel and then generates some
    network traffic.
    Once reproduced, rx err in /sys/kernel/debug/l2tp/tunnels will increase.

    Changes in v4:
    1. s/l2tp_v3_pull_opt/l2tp_v3_ensure_opt_in_linear/
    2. s/tunnel->version != L2TP_HDR_VER_2/tunnel->version == L2TP_HDR_VER_3/
    3. Add 'Fixes' in commit messages.

    Changes in v3:
    1. To keep consistency, move the code out of l2tp_recv_common.
    2. Use "net" instead of "net-next", since this is a bug fix.

    Changes in v2:
    1. Only fix L2TPv3 to make code simple.
    To fix both L2TPv3 and L2TPv2, we'd better refactor l2tp_recv_common.
    It's complicated to do so.
    2. Reloading pointers after pskb_may_pull

    Fixes: f7faffa3ff8e ("l2tp: Add L2TPv3 protocol support")
    Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support")
    Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6")
    Signed-off-by: Jacob Wen
    Acked-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Jacob Wen
     

12 Aug, 2018

1 commit

  • l2tp_session_get() is used for two different purposes. If 'tunnel' is
    NULL, the session is searched globally in the supplied network
    namespace. Otherwise it is searched exclusively in the tunnel context.

    Callers always know the context in which they need to search the
    session. But some of them do provide both a namespace and a tunnel,
    making the semantic of the call unclear.

    This patch defines l2tp_tunnel_get_session() for lookups done in a
    tunnel and restricts l2tp_session_get() to namespace searches.

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

27 Jul, 2018

1 commit

  • The tunnel reception hook is only used by l2tp_ppp for skipping PPP
    framing bytes. This is a session specific operation, but once a PPP
    session sets ->recv_payload_hook on its tunnel, all frames received by
    the tunnel will enter pppol2tp_recv_payload_hook(), including those
    targeted at Ethernet sessions (an L2TPv3 tunnel can multiplex PPP and
    Ethernet sessions).

    So this mechanism is wrong, and uselessly complex. Let's just move this
    functionality to the pppol2tp rx handler and drop ->recv_payload_hook.

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

29 Jun, 2018

1 commit

  • The poll() changes were not well thought out, and completely
    unexplained. They also caused a huge performance regression, because
    "->poll()" was no longer a trivial file operation that just called down
    to the underlying file operations, but instead did at least two indirect
    calls.

    Indirect calls are sadly slow now with the Spectre mitigation, but the
    performance problem could at least be largely mitigated by changing the
    "->get_poll_head()" operation to just have a per-file-descriptor pointer
    to the poll head instead. That gets rid of one of the new indirections.

    But that doesn't fix the new complexity that is completely unwarranted
    for the regular case. The (undocumented) reason for the poll() changes
    was some alleged AIO poll race fixing, but we don't make the common case
    slower and more complex for some uncommon special case, so this all
    really needs way more explanations and most likely a fundamental
    redesign.

    [ This revert is a revert of about 30 different commits, not reverted
    individually because that would just be unnecessarily messy - Linus ]

    Cc: Al Viro
    Cc: Christoph Hellwig
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

26 May, 2018

1 commit


06 Mar, 2018

1 commit


27 Feb, 2018

1 commit

  • The tunnel socket tunnel->sock (struct sock) is accessed when
    preparing a new ppp session on a tunnel at pppol2tp_session_init. If
    the socket is closed by a thread while another is creating a new
    session, the threads race. In pppol2tp_connect, the tunnel object may
    be created if the pppol2tp socket is associated with the special
    session_id 0 and the tunnel socket is looked up using the provided
    fd. When handling this, pppol2tp_connect cannot sock_hold the tunnel
    socket to prevent it being destroyed during pppol2tp_connect since
    this may itself may race with the socket being destroyed. Doing
    sockfd_lookup in pppol2tp_connect isn't sufficient to prevent
    tunnel->sock going away either because a given tunnel socket fd may be
    reused between calls to pppol2tp_connect. Instead, have
    l2tp_tunnel_create sock_hold the tunnel socket before it does
    sockfd_put. This ensures that the tunnel's socket is always extant
    while the tunnel object exists. Hold a ref on the socket until the
    tunnel is destroyed and ensure that all tunnel destroy paths go
    through a common function (l2tp_tunnel_delete) since this will do the
    final sock_put to release the tunnel socket.

    Since the tunnel's socket is now guaranteed to exist if the tunnel
    exists, we no longer need to use sockfd_lookup via l2tp_sock_to_tunnel
    to derive the tunnel from the socket since this is always
    sk_user_data.

    Also, sessions no longer sock_hold the tunnel socket since sessions
    already hold a tunnel ref and the tunnel sock will not be freed until
    the tunnel is freed. Removing these sock_holds in
    l2tp_session_register avoids a possible sock leak in the
    pppol2tp_connect error path if l2tp_session_register succeeds but
    attaching a ppp channel fails. The pppol2tp_connect error path could
    have been fixed instead and have the sock ref dropped when the session
    is freed, but doing a sock_put of the tunnel socket when the session
    is freed would require a new session_free callback. It is simpler to
    just remove the sock_hold of the tunnel socket in
    l2tp_session_register, now that the tunnel socket lifetime is
    guaranteed.

    Finally, some init code in l2tp_tunnel_create is reordered to ensure
    that the new tunnel object's refcount is set and the tunnel socket ref
    is taken before the tunnel socket destructor callbacks are set.

    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: 0 PID: 4360 Comm: syzbot_19c09769 Not tainted 4.16.0-rc2+ #34
    Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    RIP: 0010:pppol2tp_session_init+0x1d6/0x500
    RSP: 0018:ffff88001377fb40 EFLAGS: 00010212
    RAX: dffffc0000000000 RBX: ffff88001636a940 RCX: ffffffff84836c1d
    RDX: 0000000000000045 RSI: 0000000055976744 RDI: 0000000000000228
    RBP: ffff88001377fb60 R08: ffffffff84836bc8 R09: 0000000000000002
    R10: ffff88001377fab8 R11: 0000000000000001 R12: 0000000000000000
    R13: ffff88001636aac8 R14: ffff8800160f81c0 R15: 1ffff100026eff76
    FS: 00007ffb3ea66700(0000) GS:ffff88001a400000(0000) knlGS:0000000000000000
    CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 0000000020e77000 CR3: 0000000016261000 CR4: 00000000000006f0
    Call Trace:
    pppol2tp_connect+0xd18/0x13c0
    ? pppol2tp_session_create+0x170/0x170
    ? __might_fault+0x115/0x1d0
    ? lock_downgrade+0x860/0x860
    ? __might_fault+0xe5/0x1d0
    ? security_socket_connect+0x8e/0xc0
    SYSC_connect+0x1b6/0x310
    ? SYSC_bind+0x280/0x280
    ? __do_page_fault+0x5d1/0xca0
    ? up_read+0x1f/0x40
    ? __do_page_fault+0x3c8/0xca0
    SyS_connect+0x29/0x30
    ? SyS_accept+0x40/0x40
    do_syscall_64+0x1e0/0x730
    ? trace_hardirqs_off_thunk+0x1a/0x1c
    entry_SYSCALL_64_after_hwframe+0x42/0xb7
    RIP: 0033:0x7ffb3e376259
    RSP: 002b:00007ffeda4f6508 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
    RAX: ffffffffffffffda RBX: 0000000020e77012 RCX: 00007ffb3e376259
    RDX: 000000000000002e RSI: 0000000020e77000 RDI: 0000000000000004
    RBP: 00007ffeda4f6540 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000400b60
    R13: 00007ffeda4f6660 R14: 0000000000000000 R15: 0000000000000000
    Code: 80 3d b0 ff 06 02 00 0f 84 07 02 00 00 e8 13 d6 db fc 49 8d bc 24 28 02 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 f
    a 48 c1 ea 03 3c 02 00 0f 85 ed 02 00 00 4d 8b a4 24 28 02 00 00 e8 13 16

    Fixes: 80d84ef3ff1dd ("l2tp: prevent l2tp_tunnel_delete racing with userspace close")
    Signed-off-by: James Chapman
    Signed-off-by: David S. Miller

    James Chapman
     

13 Feb, 2018

1 commit

  • Changes since v1:
    Added changes in these files:
    drivers/infiniband/hw/usnic/usnic_transport.c
    drivers/staging/lustre/lnet/lnet/lib-socket.c
    drivers/target/iscsi/iscsi_target_login.c
    drivers/vhost/net.c
    fs/dlm/lowcomms.c
    fs/ocfs2/cluster/tcp.c
    security/tomoyo/network.c

    Before:
    All these functions either return a negative error indicator,
    or store length of sockaddr into "int *socklen" parameter
    and return zero on success.

    "int *socklen" parameter is awkward. For example, if caller does not
    care, it still needs to provide on-stack storage for the value
    it does not need.

    None of the many FOO_getname() functions of various protocols
    ever used old value of *socklen. They always just overwrite it.

    This change drops this parameter, and makes all these functions, on success,
    return length of sockaddr. It's always >= 0 and can be differentiated
    from an error.

    Tests in callers are changed from "if (err)" to "if (err < 0)", where needed.

    rpc_sockname() lost "int buflen" parameter, since its only use was
    to be passed to kernel_getsockname() as &buflen and subsequently
    not used in any way.

    Userspace API is not changed.

    text data bss dec hex filename
    30108430 2633624 873672 33615726 200ef6e vmlinux.before.o
    30108109 2633612 873672 33615393 200ee21 vmlinux.o

    Signed-off-by: Denys Vlasenko
    CC: David S. Miller
    CC: linux-kernel@vger.kernel.org
    CC: netdev@vger.kernel.org
    CC: linux-bluetooth@vger.kernel.org
    CC: linux-decnet-user@lists.sourceforge.net
    CC: linux-wireless@vger.kernel.org
    CC: linux-rdma@vger.kernel.org
    CC: linux-sctp@vger.kernel.org
    CC: linux-nfs@vger.kernel.org
    CC: linux-x25@vger.kernel.org
    Signed-off-by: David S. Miller

    Denys Vlasenko
     

10 Nov, 2017

1 commit


05 Nov, 2017

1 commit

  • Using l2tp_tunnel_find() in l2tp_ip_recv() is wrong for two reasons:

    * It doesn't take a reference on the returned tunnel, which makes the
    call racy wrt. concurrent tunnel deletion.

    * The lookup is only based on the tunnel identifier, so it can return
    a tunnel that doesn't match the packet's addresses or protocol.

    For example, a packet sent to an L2TPv3 over IPv6 tunnel can be
    delivered to an L2TPv2 over UDPv4 tunnel. This is worse than a simple
    cross-talk: when delivering the packet to an L2TP over UDP tunnel, the
    corresponding socket is UDP, where ->sk_backlog_rcv() is NULL. Calling
    sk_receive_skb() will then crash the kernel by trying to execute this
    callback.

    And l2tp_tunnel_find() isn't even needed here. __l2tp_ip_bind_lookup()
    properly checks the socket binding and connection settings. It was used
    as a fallback mechanism for finding tunnels that didn't have their data
    path registered yet. But it's not limited to this case and can be used
    to replace l2tp_tunnel_find() in the general case.

    Fix l2tp_ip6 in the same way.

    Fixes: 0d76751fad77 ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support")
    Fixes: a32e0eec7042 ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6")
    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

01 Nov, 2017

1 commit

  • The ->ref() and ->deref() callbacks are unused since PPP stopped using
    them in ee40fb2e1eb5 ("l2tp: protect sock pointer of struct pppol2tp_session with RCU").

    We can thus remove them from struct l2tp_session and drop the do_ref
    parameter of l2tp_session_get*().

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

02 Apr, 2017

1 commit

  • Taking a reference on sessions in l2tp_recv_common() is racy; this
    has to be done by the callers.

    To this end, a new function is required (l2tp_session_get()) to
    atomically lookup a session and take a reference on it. Callers then
    have to manually drop this reference.

    Fixes: fd558d186df2 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

30 Mar, 2017

1 commit


27 Feb, 2017

1 commit


11 Feb, 2017

2 commits

  • David S. Miller
     
  • udp_ioctl(), as its name suggests, is used by UDP protocols,
    but is also used by L2TP :(

    L2TP should use its own handler, because it really does not
    look the same.

    SIOCINQ for instance should not assume UDP checksum or headers.

    Thanks to Andrey and syzkaller team for providing the report
    and a nice reproducer.

    While crashes only happen on recent kernels (after commit
    7c13f97ffde6 ("udp: do fwd memory scheduling on dequeue")), this
    probably needs to be backported to older kernels.

    Fixes: 7c13f97ffde6 ("udp: do fwd memory scheduling on dequeue")
    Fixes: 85584672012e ("udp: Fix udp_poll() and ioctl()")
    Signed-off-by: Eric Dumazet
    Reported-by: Andrey Konovalov
    Acked-by: Paolo Abeni
    Signed-off-by: David S. Miller

    Eric Dumazet
     

07 Jan, 2017

4 commits


02 Jan, 2017

1 commit


01 Dec, 2016

4 commits

  • When looking up an l2tp socket, we must consider a null netdevice id as
    wild card. There are currently two problems caused by
    __l2tp_ip_bind_lookup() not considering 'dif' as wild card when set to 0:

    * A socket bound to a device (i.e. with sk->sk_bound_dev_if != 0)
    never receives any packet. Since __l2tp_ip_bind_lookup() is called
    with dif == 0 in l2tp_ip_recv(), sk->sk_bound_dev_if is always
    different from 'dif' so the socket doesn't match.

    * Two sockets, one bound to a device but not the other, can be bound
    to the same address. If the first socket binding to the address is
    the one that is also bound to a device, the second socket can bind
    to the same address without __l2tp_ip_bind_lookup() noticing the
    overlap.

    To fix this issue, we need to consider that any null device index, be
    it 'sk->sk_bound_dev_if' or 'dif', matches with any other value.
    We also need to pass the input device index to __l2tp_ip_bind_lookup()
    on reception so that sockets bound to a device never receive packets
    from other devices.

    This patch fixes l2tp_ip6 in the same way.

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     
  • It's not enough to check for sockets bound to same address at the
    beginning of l2tp_ip{,6}_bind(): even if no socket is found at that
    time, a socket with the same address could be bound before we take
    the l2tp lock again.

    This patch moves the lookup right before inserting the new socket, so
    that no change can ever happen to the list between address lookup and
    socket insertion.

    Care is taken to avoid side effects on the socket in case of failure.
    That is, modifications of the socket are done after the lookup, when
    binding is guaranteed to succeed, and before releasing the l2tp lock,
    so that concurrent lookups will always see fully initialised sockets.

    For l2tp_ip, 'ret' is set to -EINVAL before checking the SOCK_ZAPPED
    bit. Error code was mistakenly set to -EADDRINUSE on error by commit
    32c231164b76 ("l2tp: fix racy SOCK_ZAPPED flag check in l2tp_ip{,6}_bind()").
    Using -EINVAL restores original behaviour.

    For l2tp_ip6, the lookup is now always done with the correct bound
    device. Before this patch, when binding to a link-local address, the
    lookup was done with the original sk->sk_bound_dev_if, which was later
    overwritten with addr->l2tp_scope_id. Lookup is now performed with the
    final sk->sk_bound_dev_if value.

    Finally, the (addr_len >= sizeof(struct sockaddr_in6)) check has been
    dropped: addr is a sockaddr_l2tpip6 not sockaddr_in6 and addr_len has
    already been checked at this point (this part of the code seems to have
    been copy-pasted from net/ipv6/raw.c).

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     
  • Socket must be held while under the protection of the l2tp lock; there
    is no guarantee that sk remains valid after the read_unlock_bh() call.

    Same issue for l2tp_ip and l2tp_ip6.

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     
  • Socket flags aren't updated atomically, so the socket must be locked
    while reading the SOCK_ZAPPED flag.

    This issue exists for both l2tp_ip and l2tp_ip6. For IPv6, this patch
    also brings error handling for __ip6_datagram_connect() failures.

    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

20 Nov, 2016

1 commit

  • Lock socket before checking the SOCK_ZAPPED flag in l2tp_ip6_bind().
    Without lock, a concurrent call could modify the socket flags between
    the sock_flag(sk, SOCK_ZAPPED) test and the lock_sock() call. This way,
    a socket could be inserted twice in l2tp_ip6_bind_table. Releasing it
    would then leave a stale pointer there, generating use-after-free
    errors when walking through the list or modifying adjacent entries.

    BUG: KASAN: use-after-free in l2tp_ip6_close+0x22e/0x290 at addr ffff8800081b0ed8
    Write of size 8 by task syz-executor/10987
    CPU: 0 PID: 10987 Comm: syz-executor Not tainted 4.8.0+ #39
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
    ffff880031d97838 ffffffff829f835b ffff88001b5a1640 ffff8800081b0ec0
    ffff8800081b15a0 ffff8800081b6d20 ffff880031d97860 ffffffff8174d3cc
    ffff880031d978f0 ffff8800081b0e80 ffff88001b5a1640 ffff880031d978e0
    Call Trace:
    [] dump_stack+0xb3/0x118 lib/dump_stack.c:15
    [] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
    [< inline >] print_address_description mm/kasan/report.c:194
    [] kasan_report_error+0x1f6/0x4d0 mm/kasan/report.c:283
    [< inline >] kasan_report mm/kasan/report.c:303
    [] __asan_report_store8_noabort+0x3e/0x40 mm/kasan/report.c:329
    [< inline >] __write_once_size ./include/linux/compiler.h:249
    [< inline >] __hlist_del ./include/linux/list.h:622
    [< inline >] hlist_del_init ./include/linux/list.h:637
    [] l2tp_ip6_close+0x22e/0x290 net/l2tp/l2tp_ip6.c:239
    [] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
    [] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
    [] sock_release+0x8d/0x1d0 net/socket.c:570
    [] sock_close+0x16/0x20 net/socket.c:1017
    [] __fput+0x28c/0x780 fs/file_table.c:208
    [] ____fput+0x15/0x20 fs/file_table.c:244
    [] task_work_run+0xf9/0x170
    [] do_exit+0x85e/0x2a00
    [] do_group_exit+0x108/0x330
    [] get_signal+0x617/0x17a0 kernel/signal.c:2307
    [] do_signal+0x7f/0x18f0
    [] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
    [< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:190
    [] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
    [] entry_SYSCALL_64_fastpath+0xc4/0xc6
    Object at ffff8800081b0ec0, in cache L2TP/IPv6 size: 1448
    Allocated:
    PID = 10987
    [ 1116.897025] [] save_stack_trace+0x16/0x20
    [ 1116.897025] [] save_stack+0x46/0xd0
    [ 1116.897025] [] kasan_kmalloc+0xad/0xe0
    [ 1116.897025] [] kasan_slab_alloc+0x12/0x20
    [ 1116.897025] [< inline >] slab_post_alloc_hook mm/slab.h:417
    [ 1116.897025] [< inline >] slab_alloc_node mm/slub.c:2708
    [ 1116.897025] [< inline >] slab_alloc mm/slub.c:2716
    [ 1116.897025] [] kmem_cache_alloc+0xc8/0x2b0 mm/slub.c:2721
    [ 1116.897025] [] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1326
    [ 1116.897025] [] sk_alloc+0x38/0xae0 net/core/sock.c:1388
    [ 1116.897025] [] inet6_create+0x2d7/0x1000 net/ipv6/af_inet6.c:182
    [ 1116.897025] [] __sock_create+0x37b/0x640 net/socket.c:1153
    [ 1116.897025] [< inline >] sock_create net/socket.c:1193
    [ 1116.897025] [< inline >] SYSC_socket net/socket.c:1223
    [ 1116.897025] [] SyS_socket+0xef/0x1b0 net/socket.c:1203
    [ 1116.897025] [] entry_SYSCALL_64_fastpath+0x23/0xc6
    Freed:
    PID = 10987
    [ 1116.897025] [] save_stack_trace+0x16/0x20
    [ 1116.897025] [] save_stack+0x46/0xd0
    [ 1116.897025] [] kasan_slab_free+0x71/0xb0
    [ 1116.897025] [< inline >] slab_free_hook mm/slub.c:1352
    [ 1116.897025] [< inline >] slab_free_freelist_hook mm/slub.c:1374
    [ 1116.897025] [< inline >] slab_free mm/slub.c:2951
    [ 1116.897025] [] kmem_cache_free+0xc8/0x330 mm/slub.c:2973
    [ 1116.897025] [< inline >] sk_prot_free net/core/sock.c:1369
    [ 1116.897025] [] __sk_destruct+0x32b/0x4f0 net/core/sock.c:1444
    [ 1116.897025] [] sk_destruct+0x44/0x80 net/core/sock.c:1452
    [ 1116.897025] [] __sk_free+0x53/0x220 net/core/sock.c:1460
    [ 1116.897025] [] sk_free+0x23/0x30 net/core/sock.c:1471
    [ 1116.897025] [] sk_common_release+0x28c/0x3e0 ./include/net/sock.h:1589
    [ 1116.897025] [] l2tp_ip6_close+0x1fe/0x290 net/l2tp/l2tp_ip6.c:243
    [ 1116.897025] [] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
    [ 1116.897025] [] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
    [ 1116.897025] [] sock_release+0x8d/0x1d0 net/socket.c:570
    [ 1116.897025] [] sock_close+0x16/0x20 net/socket.c:1017
    [ 1116.897025] [] __fput+0x28c/0x780 fs/file_table.c:208
    [ 1116.897025] [] ____fput+0x15/0x20 fs/file_table.c:244
    [ 1116.897025] [] task_work_run+0xf9/0x170
    [ 1116.897025] [] do_exit+0x85e/0x2a00
    [ 1116.897025] [] do_group_exit+0x108/0x330
    [ 1116.897025] [] get_signal+0x617/0x17a0 kernel/signal.c:2307
    [ 1116.897025] [] do_signal+0x7f/0x18f0
    [ 1116.897025] [] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
    [ 1116.897025] [< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:190
    [ 1116.897025] [] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
    [ 1116.897025] [] entry_SYSCALL_64_fastpath+0xc4/0xc6
    Memory state around the buggy address:
    ffff8800081b0d80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    ffff8800081b0e00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
    >ffff8800081b0e80: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
    ^
    ffff8800081b0f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
    ffff8800081b0f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb

    ==================================================================

    The same issue exists with l2tp_ip_bind() and l2tp_ip_bind_table.

    Fixes: c51ce49735c1 ("l2tp: fix oops in L2TP IP sockets for connect() AF_UNSPEC case")
    Reported-by: Baozeng Ding
    Reported-by: Andrey Konovalov
    Tested-by: Baozeng Ding
    Signed-off-by: Guillaume Nault
    Signed-off-by: David S. Miller

    Guillaume Nault
     

21 Oct, 2016

1 commit

  • Baozeng Ding reported KASAN traces showing uses after free in
    udp_lib_get_port() and other related UDP functions.

    A CONFIG_DEBUG_PAGEALLOC=y kernel would eventually crash.

    I could write a reproducer with two threads doing :

    static int sock_fd;
    static void *thr1(void *arg)
    {
    for (;;) {
    connect(sock_fd, (const struct sockaddr *)arg,
    sizeof(struct sockaddr_in));
    }
    }

    static void *thr2(void *arg)
    {
    struct sockaddr_in unspec;

    for (;;) {
    memset(&unspec, 0, sizeof(unspec));
    connect(sock_fd, (const struct sockaddr *)&unspec,
    sizeof(unspec));
    }
    }

    Problem is that udp_disconnect() could run without holding socket lock,
    and this was causing list corruptions.

    Signed-off-by: Eric Dumazet
    Reported-by: Baozeng Ding
    Signed-off-by: David S. Miller

    Eric Dumazet