1. 17 8月, 2021 1 次提交
    • A
      bpf: Refactor BPF_PROG_RUN into a function · fb7dd8bc
      Andrii Nakryiko 提交于
      Turn BPF_PROG_RUN into a proper always inlined function. No functional and
      performance changes are intended, but it makes it much easier to understand
      what's going on with how BPF programs are actually get executed. It's more
      obvious what types and callbacks are expected. Also extra () around input
      parameters can be dropped, as well as `__` variable prefixes intended to avoid
      naming collisions, which makes the code simpler to read and write.
      
      This refactoring also highlighted one extra issue. BPF_PROG_RUN is both
      a macro and an enum value (BPF_PROG_RUN == BPF_PROG_TEST_RUN). Turning
      BPF_PROG_RUN into a function causes naming conflict compilation error. So
      rename BPF_PROG_RUN into lower-case bpf_prog_run(), similar to
      bpf_prog_run_xdp(), bpf_prog_run_pin_on_cpu(), etc. All existing callers of
      BPF_PROG_RUN, the macro, are switched to bpf_prog_run() explicitly.
      Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NYonghong Song <yhs@fb.com>
      Link: https://lore.kernel.org/bpf/20210815070609.987780-2-andrii@kernel.org
      fb7dd8bc
  2. 08 8月, 2021 2 次提交
    • P
      ppp: Fix generating ppp unit id when ifname is not specified · 3125f26c
      Pali Rohár 提交于
      When registering new ppp interface via PPPIOCNEWUNIT ioctl then kernel has
      to choose interface name as this ioctl API does not support specifying it.
      
      Kernel in this case register new interface with name "ppp<id>" where <id>
      is the ppp unit id, which can be obtained via PPPIOCGUNIT ioctl. This
      applies also in the case when registering new ppp interface via rtnl
      without supplying IFLA_IFNAME.
      
      PPPIOCNEWUNIT ioctl allows to specify own ppp unit id which will kernel
      assign to ppp interface, in case this ppp id is not already used by other
      ppp interface.
      
      In case user does not specify ppp unit id then kernel choose the first free
      ppp unit id. This applies also for case when creating ppp interface via
      rtnl method as it does not provide a way for specifying own ppp unit id.
      
      If some network interface (does not have to be ppp) has name "ppp<id>"
      with this first free ppp id then PPPIOCNEWUNIT ioctl or rtnl call fails.
      
      And registering new ppp interface is not possible anymore, until interface
      which holds conflicting name is renamed. Or when using rtnl method with
      custom interface name in IFLA_IFNAME.
      
      As list of allocated / used ppp unit ids is not possible to retrieve from
      kernel to userspace, userspace has no idea what happens nor which interface
      is doing this conflict.
      
      So change the algorithm how ppp unit id is generated. And choose the first
      number which is not neither used as ppp unit id nor in some network
      interface with pattern "ppp<id>".
      
      This issue can be simply reproduced by following pppd call when there is no
      ppp interface registered and also no interface with name pattern "ppp<id>":
      
          pppd ifname ppp1 +ipv6 noip noauth nolock local nodetach pty "pppd +ipv6 noip noauth nolock local nodetach notty"
      
      Or by creating the one ppp interface (which gets assigned ppp unit id 0),
      renaming it to "ppp1" and then trying to create a new ppp interface (which
      will always fails as next free ppp unit id is 1, but network interface with
      name "ppp1" exists).
      
      This patch fixes above described issue by generating new and new ppp unit
      id until some non-conflicting id with network interfaces is generated.
      Signed-off-by: NPali Rohár <pali@kernel.org>
      Cc: stable@vger.kernel.org
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      3125f26c
    • P
      ppp: Fix generating ifname when empty IFLA_IFNAME is specified · 2459dcb9
      Pali Rohár 提交于
      IFLA_IFNAME is nul-term string which means that IFLA_IFNAME buffer can be
      larger than length of string which contains.
      
      Function __rtnl_newlink() generates new own ifname if either IFLA_IFNAME
      was not specified at all or userspace passed empty nul-term string.
      
      It is expected that if userspace does not specify ifname for new ppp netdev
      then kernel generates one in format "ppp<id>" where id matches to the ppp
      unit id which can be later obtained by PPPIOCGUNIT ioctl.
      
      And it works in this way if IFLA_IFNAME is not specified at all. But it
      does not work when IFLA_IFNAME is specified with empty string.
      
      So fix this logic also for empty IFLA_IFNAME in ppp_nl_newlink() function
      and correctly generates ifname based on ppp unit identifier if userspace
      did not provided preferred ifname.
      
      Without this patch when IFLA_IFNAME was specified with empty string then
      kernel created a new ppp interface in format "ppp<id>" but id did not
      match ppp unit id returned by PPPIOCGUNIT ioctl. In this case id was some
      number generated by __rtnl_newlink() function.
      Signed-off-by: NPali Rohár <pali@kernel.org>
      Fixes: bb8082f6 ("ppp: build ifname using unit identifier for rtnl based devices")
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2459dcb9
  3. 28 7月, 2021 1 次提交
  4. 25 3月, 2021 1 次提交
  5. 09 1月, 2021 1 次提交
    • T
      ppp: fix refcount underflow on channel unbridge · c1787ffd
      Tom Parkin 提交于
      When setting up a channel bridge, ppp_bridge_channels sets the
      pch->bridge field before taking the associated reference on the bridge
      file instance.
      
      This opens up a refcount underflow bug if ppp_bridge_channels called
      via. iotcl runs concurrently with ppp_unbridge_channels executing via.
      file release.
      
      The bug is triggered by ppp_bridge_channels taking the error path
      through the 'err_unset' label.  In this scenario, pch->bridge is set,
      but the reference on the bridged channel will not be taken because
      the function errors out.  If ppp_unbridge_channels observes pch->bridge
      before it is unset by the error path, it will erroneously drop the
      reference on the bridged channel and cause a refcount underflow.
      
      To avoid this, ensure that ppp_bridge_channels holds a reference on
      each channel in advance of setting the bridge pointers.
      Signed-off-by: NTom Parkin <tparkin@katalix.com>
      Fixes: 4cf476ce ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls")
      Acked-by: NGuillaume Nault <gnault@redhat.com>
      Link: https://lore.kernel.org/r/20210107181315.3128-1-tparkin@katalix.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
      c1787ffd
  6. 11 12月, 2020 1 次提交
    • T
      ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls · 4cf476ce
      Tom Parkin 提交于
      This new ioctl pair allows two ppp channels to be bridged together:
      frames arriving in one channel are transmitted in the other channel
      and vice versa.
      
      The practical use for this is primarily to support the L2TP Access
      Concentrator use-case.  The end-user session is presented as a ppp
      channel (typically PPPoE, although it could be e.g. PPPoA, or even PPP
      over a serial link) and is switched into a PPPoL2TP session for
      transmission to the LNS.  At the LNS the PPP session is terminated in
      the ISP's network.
      
      When a PPP channel is bridged to another it takes a reference on the
      other's struct ppp_file.  This reference is dropped when the channels
      are unbridged, which can occur either explicitly on userspace calling
      the PPPIOCUNBRIDGECHAN ioctl, or implicitly when either channel in the
      bridge is unregistered.
      
      In order to implement the channel bridge, struct channel is extended
      with a new field, 'bridge', which points to the other struct channel
      making up the bridge.
      
      This pointer is RCU protected to avoid adding another lock to the data
      path.
      
      To guard against concurrent writes to the pointer, the existing struct
      channel lock 'upl' coverage is extended rather than adding a new lock.
      
      The 'upl' lock is used to protect the existing unit pointer.  Since the
      bridge effectively replaces the unit (they're mutually exclusive for a
      channel) it makes coding easier to use the same lock to cover them
      both.
      Signed-off-by: NTom Parkin <tparkin@katalix.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4cf476ce
  7. 05 5月, 2020 1 次提交
  8. 28 12月, 2019 1 次提交
  9. 06 12月, 2019 1 次提交
  10. 25 10月, 2019 1 次提交
    • T
      net: core: add generic lockdep keys · ab92d68f
      Taehee Yoo 提交于
      Some interface types could be nested.
      (VLAN, BONDING, TEAM, MACSEC, MACVLAN, IPVLAN, VIRT_WIFI, VXLAN, etc..)
      These interface types should set lockdep class because, without lockdep
      class key, lockdep always warn about unexisting circular locking.
      
      In the current code, these interfaces have their own lockdep class keys and
      these manage itself. So that there are so many duplicate code around the
      /driver/net and /net/.
      This patch adds new generic lockdep keys and some helper functions for it.
      
      This patch does below changes.
      a) Add lockdep class keys in struct net_device
         - qdisc_running, xmit, addr_list, qdisc_busylock
         - these keys are used as dynamic lockdep key.
      b) When net_device is being allocated, lockdep keys are registered.
         - alloc_netdev_mqs()
      c) When net_device is being free'd llockdep keys are unregistered.
         - free_netdev()
      d) Add generic lockdep key helper function
         - netdev_register_lockdep_key()
         - netdev_unregister_lockdep_key()
         - netdev_update_lockdep_key()
      e) Remove unnecessary generic lockdep macro and functions
      f) Remove unnecessary lockdep code of each interfaces.
      
      After this patch, each interface modules don't need to maintain
      their lockdep keys.
      Signed-off-by: NTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ab92d68f
  11. 23 10月, 2019 4 次提交
    • A
      compat_ioctl: ppp: move simple commands into ppp_generic.c · 8f5d9f2c
      Arnd Bergmann 提交于
      All ppp commands that are not already handled in ppp_compat_ioctl()
      are compatible, so they can now handled by calling the native
      ppp_ioctl() directly.
      
      Without CONFIG_BLOCK, the generic compat_ioctl table is now empty,
      so add a check to avoid a build failure in the looking function for
      that configuration.
      
      Cc: netdev@vger.kernel.org
      Cc: linux-ppp@vger.kernel.org
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: "David S. Miller" <davem@davemloft.net>
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      8f5d9f2c
    • A
      compat_ioctl: handle PPPIOCGIDLE for 64-bit time_t · 17c7e7f4
      Arnd Bergmann 提交于
      The ppp_idle structure is defined in terms of __kernel_time_t, which is
      defined as 'long' on all architectures, and this usage is not affected
      by the y2038 problem since it transports a time interval rather than an
      absolute time.
      
      However, the ppp user space defines the same structure as time_t, which
      may be 64-bit wide on new libc versions even on 32-bit architectures.
      
      It's easy enough to just handle both possible structure layouts on
      all architectures, to deal with the possibility that a user space ppp
      implementation comes with its own ppp_idle structure definition, as well
      as to document the fact that the driver is y2038-safe.
      
      Doing this also avoids the need for a special compat mode translation,
      since 32-bit and 64-bit kernels now support the same interfaces.  The old
      32-bit structure is also available on native 64-bit architectures now,
      but this is harmless.
      
      Cc: netdev@vger.kernel.org
      Cc: linux-ppp@vger.kernel.org
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: "David S. Miller" <davem@davemloft.net>
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      17c7e7f4
    • A
      compat_ioctl: move PPPIOCSCOMPRESS to ppp_generic · 5b6c02df
      Al Viro 提交于
      Rather than using a compat_alloc_user_space() buffer, moving
      this next to the native handler allows sharing most of
      the code, leaving only the user copy portion distinct.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: netdev@vger.kernel.org
      Cc: linux-ppp@vger.kernel.org
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: "David S. Miller" <davem@davemloft.net>
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      5b6c02df
    • A
      compat_ioctl: unify copy-in of ppp filters · 3e859adf
      Al Viro 提交于
      Now that isdn4linux is gone, the is only one implementation of PPPIOCSPASS
      and PPPIOCSACTIVE in ppp_generic.c, so this is where the compat_ioctl
      support should be implemented.
      
      The two commands are implemented in very similar ways, so introduce
      new helpers to allow sharing between the two and between native and
      compat mode.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      [arnd: rebased, and added changelog text]
      Cc: netdev@vger.kernel.org
      Cc: linux-ppp@vger.kernel.org
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: "David S. Miller" <davem@davemloft.net>
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      3e859adf
  12. 25 9月, 2019 1 次提交
    • T
      ppp: Fix memory leak in ppp_write · 4c247de5
      Takeshi Misawa 提交于
      When ppp is closing, __ppp_xmit_process() failed to enqueue skb
      and skb allocated in ppp_write() is leaked.
      
      syzbot reported :
      BUG: memory leak
      unreferenced object 0xffff88812a17bc00 (size 224):
        comm "syz-executor673", pid 6952, jiffies 4294942888 (age 13.040s)
        hex dump (first 32 bytes):
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        backtrace:
          [<00000000d110fff9>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline]
          [<00000000d110fff9>] slab_post_alloc_hook mm/slab.h:522 [inline]
          [<00000000d110fff9>] slab_alloc_node mm/slab.c:3262 [inline]
          [<00000000d110fff9>] kmem_cache_alloc_node+0x163/0x2f0 mm/slab.c:3574
          [<000000002d616113>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:197
          [<000000000167fc45>] alloc_skb include/linux/skbuff.h:1055 [inline]
          [<000000000167fc45>] ppp_write+0x48/0x120 drivers/net/ppp/ppp_generic.c:502
          [<000000009ab42c0b>] __vfs_write+0x43/0xa0 fs/read_write.c:494
          [<00000000086b2e22>] vfs_write fs/read_write.c:558 [inline]
          [<00000000086b2e22>] vfs_write+0xee/0x210 fs/read_write.c:542
          [<00000000a2b70ef9>] ksys_write+0x7c/0x130 fs/read_write.c:611
          [<00000000ce5e0fdd>] __do_sys_write fs/read_write.c:623 [inline]
          [<00000000ce5e0fdd>] __se_sys_write fs/read_write.c:620 [inline]
          [<00000000ce5e0fdd>] __x64_sys_write+0x1e/0x30 fs/read_write.c:620
          [<00000000d9d7b370>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:296
          [<0000000006e6d506>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      Fix this by freeing skb, if ppp is closing.
      
      Fixes: 6d066734 ("ppp: avoid loop in xmit recursion detection code")
      Reported-and-tested-by: syzbot+d9c8bf24e56416d7ce2c@syzkaller.appspotmail.com
      Signed-off-by: NTakeshi Misawa <jeliantsurux@gmail.com>
      Reviewed-by: NGuillaume Nault <gnault@redhat.com>
      Tested-by: NGuillaume Nault <gnault@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4c247de5
  13. 31 5月, 2019 1 次提交
  14. 21 12月, 2018 1 次提交
    • S
      ppp: Move PFC decompression to PPP generic layer · 7fb1b8ca
      Sam Protsenko 提交于
      Extract "Protocol" field decompression code from transport protocols to
      PPP generic layer, where it actually belongs. As a consequence, this
      patch fixes incorrect place of PFC decompression in L2TP driver (when
      it's not PPPOX_BOUND) and also enables this decompression for other
      protocols, like PPPoE.
      
      Protocol field decompression also happens in PPP Multilink Protocol
      code and in PPP compression protocols implementations (bsd, deflate,
      mppe). It looks like there is no easy way to get rid of that, so it was
      decided to leave it as is, but provide those cases with appropriate
      comments instead.
      
      Changes in v2:
        - Fix the order of checking skb data room and proto decompression
        - Remove "inline" keyword from ppp_decompress_proto()
        - Don't split line before function name
        - Prefix ppp_decompress_proto() function with "__"
        - Add ppp_decompress_proto() function with skb data room checks
        - Add description for introduced functions
        - Fix comments (as per review on mailing list)
      Signed-off-by: NSam Protsenko <semen.protsenko@linaro.org>
      Reviewed-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7fb1b8ca
  15. 11 9月, 2018 1 次提交
  16. 25 5月, 2018 1 次提交
    • E
      ppp: remove the PPPIOCDETACH ioctl · af8d3c7c
      Eric Biggers 提交于
      The PPPIOCDETACH ioctl effectively tries to "close" the given ppp file
      before f_count has reached 0, which is fundamentally a bad idea.  It
      does check 'f_count < 2', which excludes concurrent operations on the
      file since they would only be possible with a shared fd table, in which
      case each fdget() would take a file reference.  However, it fails to
      account for the fact that even with 'f_count == 1' the file can still be
      linked into epoll instances.  As reported by syzbot, this can trivially
      be used to cause a use-after-free.
      
      Yet, the only known user of PPPIOCDETACH is pppd versions older than
      ppp-2.4.2, which was released almost 15 years ago (November 2003).
      Also, PPPIOCDETACH apparently stopped working reliably at around the
      same time, when the f_count check was added to the kernel, e.g. see
      https://lkml.org/lkml/2002/12/31/83.  Also, the current 'f_count < 2'
      check makes PPPIOCDETACH only work in single-threaded applications; it
      always fails if called from a multithreaded application.
      
      All pppd versions released in the last 15 years just close() the file
      descriptor instead.
      
      Therefore, instead of hacking around this bug by exporting epoll
      internals to modules, and probably missing other related bugs, just
      remove the PPPIOCDETACH ioctl and see if anyone actually notices.  Leave
      a stub in place that prints a one-time warning and returns EINVAL.
      
      Reported-by: syzbot+16363c99d4134717c05b@syzkaller.appspotmail.com
      Fixes: 1da177e4 ("Linux-2.6.12-rc2")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Acked-by: NPaul Mackerras <paulus@ozlabs.org>
      Reviewed-by: NGuillaume Nault <g.nault@alphalink.fr>
      Tested-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      af8d3c7c
  17. 28 3月, 2018 1 次提交
  18. 27 3月, 2018 1 次提交
  19. 23 3月, 2018 1 次提交
    • G
      ppp: avoid loop in xmit recursion detection code · 6d066734
      Guillaume Nault 提交于
      We already detect situations where a PPP channel sends packets back to
      its upper PPP device. While this is enough to avoid deadlocking on xmit
      locks, this doesn't prevent packets from looping between the channel
      and the unit.
      
      The problem is that ppp_start_xmit() enqueues packets in ppp->file.xq
      before checking for xmit recursion. Therefore, __ppp_xmit_process()
      might dequeue a packet from ppp->file.xq and send it on the channel
      which, in turn, loops it back on the unit. Then ppp_start_xmit()
      queues the packet back to ppp->file.xq and __ppp_xmit_process() picks
      it up and sends it again through the channel. Therefore, the packet
      will loop between __ppp_xmit_process() and ppp_start_xmit() until some
      other part of the xmit path drops it.
      
      For L2TP, we rapidly fill the skb's headroom and pppol2tp_xmit() drops
      the packet after a few iterations. But PPTP reallocates the headroom
      if necessary, letting the loop run and exhaust the machine resources
      (as reported in https://bugzilla.kernel.org/show_bug.cgi?id=199109).
      
      Fix this by letting __ppp_xmit_process() enqueue the skb to
      ppp->file.xq, so that we can check for recursion before adding it to
      the queue. Now ppp_xmit_process() can drop the packet when recursion is
      detected.
      
      __ppp_channel_push() is a bit special. It calls __ppp_xmit_process()
      without having any actual packet to send. This is used by
      ppp_output_wakeup() to re-enable transmission on the parent unit (for
      implementations like ppp_async.c, where the .start_xmit() function
      might not consume the skb, leaving it in ppp->xmit_pending and
      disabling transmission).
      Therefore, __ppp_xmit_process() needs to handle the case where skb is
      NULL, dequeuing as many packets as possible from ppp->file.xq.
      Reported-by: Nxu heng <xuheng333@zoho.com>
      Fixes: 55454a56 ("ppp: avoid dealock on recursive xmit")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6d066734
  20. 05 3月, 2018 1 次提交
    • G
      ppp: prevent unregistered channels from connecting to PPP units · 77f840e3
      Guillaume Nault 提交于
      PPP units don't hold any reference on the channels connected to it.
      It is the channel's responsibility to ensure that it disconnects from
      its unit before being destroyed.
      In practice, this is ensured by ppp_unregister_channel() disconnecting
      the channel from the unit before dropping a reference on the channel.
      
      However, it is possible for an unregistered channel to connect to a PPP
      unit: register a channel with ppp_register_net_channel(), attach a
      /dev/ppp file to it with ioctl(PPPIOCATTCHAN), unregister the channel
      with ppp_unregister_channel() and finally connect the /dev/ppp file to
      a PPP unit with ioctl(PPPIOCCONNECT).
      
      Once in this situation, the channel is only held by the /dev/ppp file,
      which can be released at anytime and free the channel without letting
      the parent PPP unit know. Then the ppp structure ends up with dangling
      pointers in its ->channels list.
      
      Prevent this scenario by forbidding unregistered channels from
      connecting to PPP units. This maintains the code logic by keeping
      ppp_unregister_channel() responsible from disconnecting the channel if
      necessary and avoids modification on the reference counting mechanism.
      
      This issue seems to predate git history (successfully reproduced on
      Linux 2.6.26 and earlier PPP commits are unrelated).
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      77f840e3
  21. 28 2月, 2018 1 次提交
  22. 12 2月, 2018 1 次提交
    • L
      vfs: do bulk POLL* -> EPOLL* replacement · a9a08845
      Linus Torvalds 提交于
      This is the mindless scripted replacement of kernel use of POLL*
      variables as described by Al, done by this script:
      
          for V in IN OUT PRI ERR RDNORM RDBAND WRNORM WRBAND HUP RDHUP NVAL MSG; do
              L=`git grep -l -w POLL$V | grep -v '^t' | grep -v /um/ | grep -v '^sa' | grep -v '/poll.h$'|grep -v '^D'`
              for f in $L; do sed -i "-es/^\([^\"]*\)\(\<POLL$V\>\)/\\1E\\2/" $f; done
          done
      
      with de-mangling cleanups yet to come.
      
      NOTE! On almost all architectures, the EPOLL* constants have the same
      values as the POLL* constants do.  But they keyword here is "almost".
      For various bad reasons they aren't the same, and epoll() doesn't
      actually work quite correctly in some cases due to this on Sparc et al.
      
      The next patch from Al will sort out the final differences, and we
      should be all done.
      Scripted-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a9a08845
  23. 16 1月, 2018 1 次提交
    • G
      ppp: unlock all_ppp_mutex before registering device · 0171c418
      Guillaume Nault 提交于
      ppp_dev_uninit(), which is the .ndo_uninit() handler of PPP devices,
      needs to lock pn->all_ppp_mutex. Therefore we mustn't call
      register_netdevice() with pn->all_ppp_mutex already locked, or we'd
      deadlock in case register_netdevice() fails and calls .ndo_uninit().
      
      Fortunately, we can unlock pn->all_ppp_mutex before calling
      register_netdevice(). This lock protects pn->units_idr, which isn't
      used in the device registration process.
      
      However, keeping pn->all_ppp_mutex locked during device registration
      did ensure that no device in transient state would be published in
      pn->units_idr. In practice, unlocking it before calling
      register_netdevice() doesn't change this property: ppp_unit_register()
      is called with 'ppp_mutex' locked and all searches done in
      pn->units_idr hold this lock too.
      
      Fixes: 8cb775bc ("ppp: fix device unregistration upon netns deletion")
      Reported-and-tested-by: syzbot+367889b9c9e279219175@syzkaller.appspotmail.com
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0171c418
  24. 29 11月, 2017 1 次提交
  25. 14 11月, 2017 1 次提交
  26. 01 11月, 2017 1 次提交
  27. 29 10月, 2017 1 次提交
  28. 22 10月, 2017 1 次提交
  29. 07 10月, 2017 1 次提交
    • G
      ppp: fix race in ppp device destruction · 6151b8b3
      Guillaume Nault 提交于
      ppp_release() tries to ensure that netdevices are unregistered before
      decrementing the unit refcount and running ppp_destroy_interface().
      
      This is all fine as long as the the device is unregistered by
      ppp_release(): the unregister_netdevice() call, followed by
      rtnl_unlock(), guarantee that the unregistration process completes
      before rtnl_unlock() returns.
      
      However, the device may be unregistered by other means (like
      ppp_nl_dellink()). If this happens right before ppp_release() calling
      rtnl_lock(), then ppp_release() has to wait for the concurrent
      unregistration code to release the lock.
      But rtnl_unlock() releases the lock before completing the device
      unregistration process. This allows ppp_release() to proceed and
      eventually call ppp_destroy_interface() before the unregistration
      process completes. Calling free_netdev() on this partially unregistered
      device will BUG():
      
       ------------[ cut here ]------------
       kernel BUG at net/core/dev.c:8141!
       invalid opcode: 0000 [#1] SMP
      
       CPU: 1 PID: 1557 Comm: pppd Not tainted 4.14.0-rc2+ #4
       Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1.fc26 04/01/2014
      
       Call Trace:
        ppp_destroy_interface+0xd8/0xe0 [ppp_generic]
        ppp_disconnect_channel+0xda/0x110 [ppp_generic]
        ppp_unregister_channel+0x5e/0x110 [ppp_generic]
        pppox_unbind_sock+0x23/0x30 [pppox]
        pppoe_connect+0x130/0x440 [pppoe]
        SYSC_connect+0x98/0x110
        ? do_fcntl+0x2c0/0x5d0
        SyS_connect+0xe/0x10
        entry_SYSCALL_64_fastpath+0x1a/0xa5
      
       RIP: free_netdev+0x107/0x110 RSP: ffffc28a40573d88
       ---[ end trace ed294ff0cc40eeff ]---
      
      We could set the ->needs_free_netdev flag on PPP devices and move the
      ppp_destroy_interface() logic in the ->priv_destructor() callback. But
      that'd be quite intrusive as we'd first need to unlink from the other
      channels and units that depend on the device (the ones that used the
      PPPIOCCONNECT and PPPIOCATTACH ioctls).
      
      Instead, we can just let the netdevice hold a reference on its
      ppp_file. This reference is dropped in ->priv_destructor(), at the very
      end of the unregistration process, so that neither ppp_release() nor
      ppp_disconnect_channel() can call ppp_destroy_interface() in the interim.
      Reported-by: NBeniamino Galvani <bgalvani@redhat.com>
      Fixes: 8cb775bc ("ppp: fix device unregistration upon netns deletion")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6151b8b3
  30. 01 10月, 2017 1 次提交
  31. 09 8月, 2017 1 次提交
    • G
      ppp: fix xmit recursion detection on ppp channels · 0a0e1a85
      Guillaume Nault 提交于
      Commit e5dadc65 ("ppp: Fix false xmit recursion detect with two ppp
      devices") dropped the xmit_recursion counter incrementation in
      ppp_channel_push() and relied on ppp_xmit_process() for this task.
      But __ppp_channel_push() can also send packets directly (using the
      .start_xmit() channel callback), in which case the xmit_recursion
      counter isn't incremented anymore. If such packets get routed back to
      the parent ppp unit, ppp_xmit_process() won't notice the recursion and
      will call ppp_channel_push() on the same channel, effectively creating
      the deadlock situation that the xmit_recursion mechanism was supposed
      to prevent.
      
      This patch re-introduces the xmit_recursion counter incrementation in
      ppp_channel_push(). Since the xmit_recursion variable is now part of
      the parent ppp unit, incrementation is skipped if the channel doesn't
      have any. This is fine because only packets routed through the parent
      unit may enter the channel recursively.
      
      Finally, we have to ensure that pch->ppp is not going to be modified
      while executing ppp_channel_push(). Instead of taking this lock only
      while calling ppp_xmit_process(), we now have to hold it for the full
      ppp_channel_push() execution. This respects the ppp locks ordering
      which requires locking ->upl before ->downl.
      
      Fixes: e5dadc65 ("ppp: Fix false xmit recursion detect with two ppp devices")
      Signed-off-by: NGuillaume Nault <g.nault@alphalink.fr>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0a0e1a85
  32. 19 7月, 2017 1 次提交
  33. 27 6月, 2017 2 次提交
  34. 16 6月, 2017 1 次提交
    • J
      networking: make skb_push & __skb_push return void pointers · d58ff351
      Johannes Berg 提交于
      It seems like a historic accident that these return unsigned char *,
      and in many places that means casts are required, more often than not.
      
      Make these functions return void * and remove all the casts across
      the tree, adding a (u8 *) cast only where the unsigned char pointer
      was used directly, all done with the following spatch:
      
          @@
          expression SKB, LEN;
          typedef u8;
          identifier fn = { skb_push, __skb_push, skb_push_rcsum };
          @@
          - *(fn(SKB, LEN))
          + *(u8 *)fn(SKB, LEN)
      
          @@
          expression E, SKB, LEN;
          identifier fn = { skb_push, __skb_push, skb_push_rcsum };
          type T;
          @@
          - E = ((T *)(fn(SKB, LEN)))
          + E = fn(SKB, LEN)
      
          @@
          expression SKB, LEN;
          identifier fn = { skb_push, __skb_push, skb_push_rcsum };
          @@
          - fn(SKB, LEN)[0]
          + *(u8 *)fn(SKB, LEN)
      
      Note that the last part there converts from push(...)[0] to the
      more idiomatic *(u8 *)push(...).
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d58ff351
  35. 01 6月, 2017 1 次提交