1. 31 7月, 2020 2 次提交
    • T
      l2tp: don't export tunnel and session free functions · 52016e25
      Tom Parkin 提交于
      Tunnel and session instances are reference counted, and shouldn't be
      directly freed by pseudowire code.
      
      Rather than exporting l2tp_tunnel_free and l2tp_session_free, make them
      private to l2tp_core.c, and export the refcount functions instead.
      
      In order to do this, the refcount functions cannot be declared as
      inline.  Since the codepaths which take and drop tunnel and session
      references are not directly in the datapath this shouldn't cause
      performance issues.
      Signed-off-by: NTom Parkin <tparkin@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      52016e25
    • T
      l2tp: don't export __l2tp_session_unhash · b2aecfe8
      Tom Parkin 提交于
      When __l2tp_session_unhash was first added it was used outside of
      l2tp_core.c, but that's no longer the case.
      
      As such, there's no longer a need to export the function.  Make it
      private inside l2tp_core.c, and relocate it to avoid having to declare
      the function prototype in l2tp_core.h.
      
      Since the function is no longer used outside l2tp_core.c, remove the
      "__" prefix since we don't need to indicate anything special about its
      expected use to callers.
      Signed-off-by: NTom Parkin <tparkin@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b2aecfe8
  2. 23 7月, 2020 3 次提交
  3. 29 2月, 2020 1 次提交
    • G
      l2tp: Replace zero-length array with flexible-array member · af71b090
      Gustavo A. R. Silva 提交于
      The current codebase makes use of the zero-length array language
      extension to the C90 standard, but the preferred mechanism to declare
      variable-length types such as these ones is a flexible array member[1][2],
      introduced in C99:
      
      struct foo {
              int stuff;
              struct boo array[];
      };
      
      By making use of the mechanism above, we will get a compiler warning
      in case the flexible array does not occur last in the structure, which
      will help us prevent some kind of undefined behavior bugs from being
      inadvertently introduced[3] to the codebase from now on.
      
      Also, notice that, dynamic memory allocations won't be affected by
      this change:
      
      "Flexible array members have incomplete type, and so the sizeof operator
      may not be applied. As a quirk of the original implementation of
      zero-length arrays, sizeof evaluates to zero."[1]
      
      Lastly, fix the following checkpatch warning:
      CHECK: Prefer kernel type 'u8' over 'uint8_t'
      #50: FILE: net/l2tp/l2tp_core.h:119:
      +	uint8_t			priv[];	/* private data */
      
      This issue was found with the help of Coccinelle.
      
      [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
      [2] https://github.com/KSPP/linux/issues/21
      [3] commit 76497732 ("cxgb3/l2t: Fix undefined behaviour")
      Signed-off-by: NGustavo A. R. Silva <gustavo@embeddedor.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      af71b090
  4. 19 6月, 2019 1 次提交
  5. 31 1月, 2019 1 次提交
    • J
      l2tp: fix reading optional fields of L2TPv3 · 4522a70d
      Jacob Wen 提交于
      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: f7faffa3 ("l2tp: Add L2TPv3 protocol support")
      Fixes: 0d76751f ("l2tp: Add L2TPv3 IP encapsulation (no UDP) support")
      Fixes: a32e0eec ("l2tp: introduce L2TPv3 IP encapsulation support for IPv6")
      Signed-off-by: NJacob Wen <jian.w.wen@oracle.com>
      Acked-by: NGuillaume Nault <gnault@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4522a70d
  6. 14 8月, 2018 1 次提交
    • A
      l2tp: fix unused function warning · c2ebc256
      Arnd Bergmann 提交于
      Removing one of the callers of pppol2tp_session_get_sock caused a harmless
      warning in some configurations:
      
      net/l2tp/l2tp_ppp.c:142:21: 'pppol2tp_session_get_sock' defined but not used [-Wunused-function]
      
      Rather than adding another #ifdef here, using a proper IS_ENABLED()
      check makes the code more readable and avoids those warnings while
      letting the compiler figure out for itself which code is needed.
      
      This adds one pointer for the unused show() callback in struct
      l2tp_session, but that seems harmless.
      
      Fixes: b0e29063 ("l2tp: remove pppol2tp_session_ioctl()")
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c2ebc256
  7. 12 8月, 2018 2 次提交
  8. 04 8月, 2018 2 次提交
    • G
      l2tp: ignore L2TP_ATTR_MTU · e9697e2e
      Guillaume Nault 提交于
      This attribute's handling is broken. It can only be used when creating
      Ethernet pseudo-wires, in which case its value can be used as the
      initial MTU for the l2tpeth device.
      However, when handling update requests, L2TP_ATTR_MTU only modifies
      session->mtu. This value is never propagated to the l2tpeth device.
      Dump requests also return the value of session->mtu, which is not
      synchronised anymore with the device MTU.
      
      The same problem occurs if the device MTU is properly updated using the
      generic IFLA_MTU attribute. In this case, session->mtu is not updated,
      and L2TP_ATTR_MTU will report an invalid value again when dumping the
      session.
      
      It does not seem worthwhile to complexify l2tp_eth.c to synchronise
      session->mtu with the device MTU. Even the ip-l2tp manpage advises to
      use 'ip link' to initialise the MTU of l2tpeth devices (iproute2 does
      not handle L2TP_ATTR_MTU at all anyway). So let's just ignore it
      entirely.
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e9697e2e
    • G
      l2tp: define l2tp_tunnel_dst_mtu() · 1f5cd2a0
      Guillaume Nault 提交于
      Consolidate retrieval of tunnel's socket mtu in order to simplify
      l2tp_eth and l2tp_ppp a bit.
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1f5cd2a0
  9. 28 7月, 2018 3 次提交
  10. 27 7月, 2018 1 次提交
    • G
      l2tp: remove ->recv_payload_hook · 2b139e6b
      Guillaume Nault 提交于
      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: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2b139e6b
  11. 26 6月, 2018 4 次提交
  12. 14 4月, 2018 2 次提交
  13. 12 4月, 2018 2 次提交
    • G
      l2tp: fix race in duplicate tunnel detection · f6cd651b
      Guillaume Nault 提交于
      We can't use l2tp_tunnel_find() to prevent l2tp_nl_cmd_tunnel_create()
      from creating a duplicate tunnel. A tunnel can be concurrently
      registered after l2tp_tunnel_find() returns. Therefore, searching for
      duplicates must be done at registration time.
      
      Finally, remove l2tp_tunnel_find() entirely as it isn't use anywhere
      anymore.
      
      Fixes: 309795f4 ("l2tp: Add netlink control API for L2TP")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f6cd651b
    • G
      l2tp: fix races in tunnel creation · 6b9f3423
      Guillaume Nault 提交于
      l2tp_tunnel_create() inserts the new tunnel into the namespace's tunnel
      list and sets the socket's ->sk_user_data field, before returning it to
      the caller. Therefore, there are two ways the tunnel can be accessed
      and freed, before the caller even had the opportunity to take a
      reference. In practice, syzbot could crash the module by closing the
      socket right after a new tunnel was returned to pppol2tp_create().
      
      This patch moves tunnel registration out of l2tp_tunnel_create(), so
      that the caller can safely hold a reference before publishing the
      tunnel. This second step is done with the new l2tp_tunnel_register()
      function, which is now responsible for associating the tunnel to its
      socket and for inserting it into the namespace's list.
      
      While moving the code to l2tp_tunnel_register(), a few modifications
      have been done. First, the socket validation tests are done in a helper
      function, for clarity. Also, modifying the socket is now done after
      having inserted the tunnel to the namespace's tunnels list. This will
      allow insertion to fail, without having to revert theses modifications
      in the error path (a followup patch will check for duplicate tunnels
      before insertion). Either the socket is a kernel socket which we
      control, or it is a user-space socket for which we have a reference on
      the file descriptor. In any case, the socket isn't going to be closed
      from under us.
      
      Reported-by: syzbot+fbeeb5c3b538e8545644@syzkaller.appspotmail.com
      Fixes: fd558d18 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6b9f3423
  14. 13 3月, 2018 1 次提交
    • P
      l2tp: fix races with ipv4-mapped ipv6 addresses · b954f940
      Paolo Abeni 提交于
      The l2tp_tunnel_create() function checks for v4mapped ipv6
      sockets and cache that flag, so that l2tp core code can
      reusing it at xmit time.
      
      If the socket is provided by the userspace, the connection
      status of the tunnel sockets can change between the tunnel
      creation and the xmit call, so that syzbot is able to
      trigger the following splat:
      
      BUG: KASAN: use-after-free in ip6_dst_idev include/net/ip6_fib.h:192
      [inline]
      BUG: KASAN: use-after-free in ip6_xmit+0x1f76/0x2260
      net/ipv6/ip6_output.c:264
      Read of size 8 at addr ffff8801bd949318 by task syz-executor4/23448
      
      CPU: 0 PID: 23448 Comm: syz-executor4 Not tainted 4.16.0-rc4+ #65
      Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
      Google 01/01/2011
      Call Trace:
        __dump_stack lib/dump_stack.c:17 [inline]
        dump_stack+0x194/0x24d lib/dump_stack.c:53
        print_address_description+0x73/0x250 mm/kasan/report.c:256
        kasan_report_error mm/kasan/report.c:354 [inline]
        kasan_report+0x23c/0x360 mm/kasan/report.c:412
        __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
        ip6_dst_idev include/net/ip6_fib.h:192 [inline]
        ip6_xmit+0x1f76/0x2260 net/ipv6/ip6_output.c:264
        inet6_csk_xmit+0x2fc/0x580 net/ipv6/inet6_connection_sock.c:139
        l2tp_xmit_core net/l2tp/l2tp_core.c:1053 [inline]
        l2tp_xmit_skb+0x105f/0x1410 net/l2tp/l2tp_core.c:1148
        pppol2tp_sendmsg+0x470/0x670 net/l2tp/l2tp_ppp.c:341
        sock_sendmsg_nosec net/socket.c:630 [inline]
        sock_sendmsg+0xca/0x110 net/socket.c:640
        ___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
        __sys_sendmsg+0xe5/0x210 net/socket.c:2080
        SYSC_sendmsg net/socket.c:2091 [inline]
        SyS_sendmsg+0x2d/0x50 net/socket.c:2087
        do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
        entry_SYSCALL_64_after_hwframe+0x42/0xb7
      RIP: 0033:0x453e69
      RSP: 002b:00007f819593cc68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
      RAX: ffffffffffffffda RBX: 00007f819593d6d4 RCX: 0000000000453e69
      RDX: 0000000000000081 RSI: 000000002037ffc8 RDI: 0000000000000004
      RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
      R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
      R13: 00000000000004c3 R14: 00000000006f72e8 R15: 0000000000000000
      
      This change addresses the issues:
      * explicitly checking for TCP_ESTABLISHED for user space provided sockets
      * dropping the v4mapped flag usage - it can become outdated - and
        explicitly invoking ipv6_addr_v4mapped() instead
      
      The issue is apparently there since ancient times.
      
      v1 -> v2: (many thanks to Guillaume)
       - with csum issue introduced in v1
       - replace pr_err with pr_debug
       - fix build issue with IPV6 disabled
       - move l2tp_sk_is_v4mapped in l2tp_core.c
      
      v2 -> v3:
       - don't update inet_daddr for v4mapped address, unneeded
       - drop rendundant check at creation time
      
      Reported-and-tested-by: syzbot+92fa328176eb07e4ac1a@syzkaller.appspotmail.com
      Fixes: 3557baab ("[L2TP]: PPP over L2TP driver core")
      Signed-off-by: NPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b954f940
  15. 27 2月, 2018 1 次提交
    • J
      l2tp: fix races with tunnel socket close · d00fa9ad
      James Chapman 提交于
      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 <80> 3c 02 00 0f 85 ed 02 00 00 4d 8b a4 24 28 02 00 00 e8 13 16
      
      Fixes: 80d84ef3 ("l2tp: prevent l2tp_tunnel_delete racing with userspace close")
      Signed-off-by: NJames Chapman <jchapman@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d00fa9ad
  16. 20 1月, 2018 2 次提交
  17. 06 1月, 2018 2 次提交
    • J
      l2tp: remove configurable payload offset · 900631ee
      James Chapman 提交于
      If L2TP_ATTR_OFFSET is set to a non-zero value in L2TPv3 tunnels, it
      results in L2TPv3 packets being transmitted which might not be
      compliant with the L2TPv3 RFC. This patch has l2tp ignore the offset
      setting and send all packets with no offset.
      
      In more detail:
      
      L2TPv2 supports a variable offset from the L2TPv2 header to the
      payload. The offset value is indicated by an optional field in the
      L2TP header.  Our L2TP implementation already detects the presence of
      the optional offset and skips that many bytes when handling data
      received packets. All transmitted packets are always transmitted with
      no offset.
      
      L2TPv3 has no optional offset field in the L2TPv3 packet
      header. Instead, L2TPv3 defines optional fields in a "Layer-2 Specific
      Sublayer". At the time when the original L2TP code was written, there
      was talk at IETF of offset being implemented in a new Layer-2 Specific
      Sublayer. A L2TP_ATTR_OFFSET netlink attribute was added so that this
      offset could be configured and the intention was to allow it to be
      also used to set the tx offset for L2TPv2. However, no L2TPv3 offset
      was ever specified and the L2TP_ATTR_OFFSET parameter was forgotten
      about.
      
      Setting L2TP_ATTR_OFFSET results in L2TPv3 packets being transmitted
      with the specified number of bytes padding between L2TPv3 header and
      payload. This is not compliant with L2TPv3 RFC3931. This change
      removes the configurable offset altogether while retaining
      L2TP_ATTR_OFFSET for backwards compatibility. Any L2TP_ATTR_OFFSET
      value is ignored.
      Signed-off-by: NJames Chapman <jchapman@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      900631ee
    • J
      l2tp: revert "l2tp: add peer_offset parameter" · 863def15
      James Chapman 提交于
      Revert commit f15bc54e ("l2tp: add peer_offset parameter"). This
      is removed because it is adding another configurable offset and
      configurable offsets are being removed.
      Signed-off-by: NJames Chapman <jchapman@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      863def15
  18. 28 12月, 2017 1 次提交
  19. 01 11月, 2017 2 次提交
  20. 29 10月, 2017 1 次提交
    • G
      l2tp: don't register sessions in l2tp_session_create() · 3953ae7b
      Guillaume Nault 提交于
      Sessions created by l2tp_session_create() aren't fully initialised:
      some pseudo-wire specific operations need to be done before making the
      session usable. Therefore the PPP and Ethernet pseudo-wires continue
      working on the returned l2tp session while it's already been exposed to
      the rest of the system.
      This can lead to various issues. In particular, the session may enter
      the deletion process before having been fully initialised, which will
      confuse the session removal code.
      
      This patch moves session registration out of l2tp_session_create(), so
      that callers can control when the session is exposed to the rest of the
      system. This is done by the new l2tp_session_register() function.
      
      Only pppol2tp_session_create() can be easily converted to avoid
      modifying its session after registration (the debug message is dropped
      in order to avoid the need for holding a reference on the session).
      
      For pppol2tp_connect() and l2tp_eth_create()), more work is needed.
      That'll be done in followup patches. For now, let's just register the
      session right after its creation, like it was done before. The only
      difference is that we can easily take a reference on the session before
      registering it, so, at least, we're sure it's not going to be freed
      while we're working on it.
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      3953ae7b
  21. 27 9月, 2017 1 次提交
    • S
      l2tp: fix race condition in l2tp_tunnel_delete · 62b982ee
      Sabrina Dubroca 提交于
      If we try to delete the same tunnel twice, the first delete operation
      does a lookup (l2tp_tunnel_get), finds the tunnel, calls
      l2tp_tunnel_delete, which queues it for deletion by
      l2tp_tunnel_del_work.
      
      The second delete operation also finds the tunnel and calls
      l2tp_tunnel_delete. If the workqueue has already fired and started
      running l2tp_tunnel_del_work, then l2tp_tunnel_delete will queue the
      same tunnel a second time, and try to free the socket again.
      
      Add a dead flag to prevent firing the workqueue twice. Then we can
      remove the check of queue_work's result that was meant to prevent that
      race but doesn't.
      
      Reproducer:
      
          ip l2tp add tunnel tunnel_id 3000 peer_tunnel_id 4000 local 192.168.0.2 remote 192.168.0.1 encap udp udp_sport 5000 udp_dport 6000
          ip l2tp add session name l2tp1 tunnel_id 3000 session_id 1000 peer_session_id 2000
          ip link set l2tp1 up
          ip l2tp del tunnel tunnel_id 3000
          ip l2tp del tunnel tunnel_id 3000
      
      Fixes: f8ccac0e ("l2tp: put tunnel socket release on a workqueue")
      Reported-by: NJianlin Shi <jishi@redhat.com>
      Signed-off-by: NSabrina Dubroca <sd@queasysnail.net>
      Acked-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      62b982ee
  22. 26 9月, 2017 1 次提交
    • G
      l2tp: fix race between l2tp_session_delete() and l2tp_tunnel_closeall() · b228a940
      Guillaume Nault 提交于
      There are several ways to remove L2TP sessions:
      
        * deleting a session explicitly using the netlink interface (with
          L2TP_CMD_SESSION_DELETE),
        * deleting the session's parent tunnel (either by closing the
          tunnel's file descriptor or using the netlink interface),
        * closing the PPPOL2TP file descriptor of a PPP pseudo-wire.
      
      In some cases, when these methods are used concurrently on the same
      session, the session can be removed twice, leading to use-after-free
      bugs.
      
      This patch adds a 'dead' flag, used by l2tp_session_delete() and
      l2tp_tunnel_closeall() to prevent them from stepping on each other's
      toes.
      
      The session deletion path used when closing a PPPOL2TP file descriptor
      doesn't need to be adapted. It already has to ensure that a session
      remains valid for the lifetime of its PPPOL2TP file descriptor.
      So it takes an extra reference on the session in the ->session_close()
      callback (pppol2tp_session_close()), which is eventually dropped
      in the ->sk_destruct() callback of the PPPOL2TP socket
      (pppol2tp_session_destruct()).
      Still, __l2tp_session_unhash() and l2tp_session_queue_purge() can be
      called twice and even concurrently for a given session, but thanks to
      proper locking and re-initialisation of list fields, this is not an
      issue.
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b228a940
  23. 04 9月, 2017 2 次提交
    • G
      l2tp: pass tunnel pointer to ->session_create() · f026bc29
      Guillaume Nault 提交于
      Using l2tp_tunnel_find() in pppol2tp_session_create() and
      l2tp_eth_create() is racy, because no reference is held on the
      returned session. These functions are only used to implement the
      ->session_create callback which is run by l2tp_nl_cmd_session_create().
      Therefore searching for the parent tunnel isn't necessary because
      l2tp_nl_cmd_session_create() already has a pointer to it and holds a
      reference.
      
      This patch modifies ->session_create()'s prototype to directly pass the
      the parent tunnel as parameter, thus avoiding searching for it in
      pppol2tp_session_create() and l2tp_eth_create().
      
      Since we have to touch the ->session_create() call in
      l2tp_nl_cmd_session_create(), let's also remove the useless conditional:
      we know that ->session_create isn't NULL at this point because it's
      already been checked earlier in this same function.
      
      Finally, one might be tempted to think that the removed
      l2tp_tunnel_find() calls were harmless because they would return the
      same tunnel as the one held by l2tp_nl_cmd_session_create() anyway.
      But that tunnel might be removed and a new one created with same tunnel
      Id before the l2tp_tunnel_find() call. In this case l2tp_tunnel_find()
      would return the new tunnel which wouldn't be protected by the
      reference held by l2tp_nl_cmd_session_create().
      
      Fixes: 309795f4 ("l2tp: Add netlink control API for L2TP")
      Fixes: d9e31d17 ("l2tp: Add L2TP ethernet pseudowire support")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f026bc29
    • G
      l2tp: prevent creation of sessions on terminated tunnels · f3c66d4e
      Guillaume Nault 提交于
      l2tp_tunnel_destruct() sets tunnel->sock to NULL, then removes the
      tunnel from the pernet list and finally closes all its sessions.
      Therefore, it's possible to add a session to a tunnel that is still
      reachable, but for which tunnel->sock has already been reset. This can
      make l2tp_session_create() dereference a NULL pointer when calling
      sock_hold(tunnel->sock).
      
      This patch adds the .acpt_newsess field to struct l2tp_tunnel, which is
      used by l2tp_tunnel_closeall() to prevent addition of new sessions to
      tunnels. Resetting tunnel->sock is done after l2tp_tunnel_closeall()
      returned, so that l2tp_session_add_to_tunnel() can safely take a
      reference on it when .acpt_newsess is true.
      
      The .acpt_newsess field is modified in l2tp_tunnel_closeall(), rather
      than in l2tp_tunnel_destruct(), so that it benefits all tunnel removal
      mechanisms. E.g. on UDP tunnels, a session could be added to a tunnel
      after l2tp_udp_encap_destroy() proceeded. This would prevent the tunnel
      from being removed because of the references held by this new session
      on the tunnel and its socket. Even though the session could be removed
      manually later on, this defeats the purpose of
      commit 9980d001 ("l2tp: add udp encap socket destroy handler").
      
      Fixes: fd558d18 ("l2tp: Split pppol2tp patch into separate l2tp and ppp parts")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f3c66d4e
  24. 29 8月, 2017 1 次提交
    • G
      l2tp: hold tunnel while looking up sessions in l2tp_netlink · 54652eb1
      Guillaume Nault 提交于
      l2tp_tunnel_find() doesn't take a reference on the returned tunnel.
      Therefore, it's unsafe to use it because the returned tunnel can go
      away on us anytime.
      
      Fix this by defining l2tp_tunnel_get(), which works like
      l2tp_tunnel_find(), but takes a reference on the returned tunnel.
      Caller then has to drop this reference using l2tp_tunnel_dec_refcount().
      
      As l2tp_tunnel_dec_refcount() needs to be moved to l2tp_core.h, let's
      simplify the patch and not move the L2TP_REFCNT_DEBUG part. This code
      has been broken (not even compiling) in May 2012 by
      commit a4ca44fa ("net: l2tp: Standardize logging styles")
      and fixed more than two years later by
      commit 29abe2fd ("l2tp: fix missing line continuation"). So it
      doesn't appear to be used by anyone.
      
      Same thing for l2tp_tunnel_free(); instead of moving it to l2tp_core.h,
      let's just simplify things and call kfree_rcu() directly in
      l2tp_tunnel_dec_refcount(). Extra assertions and debugging code
      provided by l2tp_tunnel_free() didn't help catching any of the
      reference counting and socket handling issues found while working on
      this series.
      
      Fixes: 309795f4 ("l2tp: Add netlink control API for L2TP")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      54652eb1