1. 27 12月, 2019 2 次提交
    • B
      usbnet: ignore endpoints with invalid wMaxPacketSize · a46cd855
      Bjørn Mork 提交于
      [ Upstream commit 8d3d7c2029c1b360f1a6b0a2fca470b57eb575c0 ]
      
      Endpoints with zero wMaxPacketSize are not usable for transferring
      data. Ignore such endpoints when looking for valid in, out and
      status pipes, to make the drivers more robust against invalid and
      meaningless descriptors.
      
      The wMaxPacketSize of these endpoints are used for memory allocations
      and as divisors in many usbnet minidrivers. Avoiding zero is therefore
      critical.
      Signed-off-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NJakub Kicinski <jakub.kicinski@netronome.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      a46cd855
    • K
      usbnet: fix kernel crash after disconnect · b650ff54
      Kloetzke Jan 提交于
      [ Upstream commit ad70411a978d1e6e97b1e341a7bde9a79af0c93d ]
      
      When disconnecting cdc_ncm the kernel sporadically crashes shortly
      after the disconnect:
      
        [   57.868812] Unable to handle kernel NULL pointer dereference at virtual address 00000000
        ...
        [   58.006653] PC is at 0x0
        [   58.009202] LR is at call_timer_fn+0xec/0x1b4
        [   58.013567] pc : [<0000000000000000>] lr : [<ffffff80080f5130>] pstate: 00000145
        [   58.020976] sp : ffffff8008003da0
        [   58.024295] x29: ffffff8008003da0 x28: 0000000000000001
        [   58.029618] x27: 000000000000000a x26: 0000000000000100
        [   58.034941] x25: 0000000000000000 x24: ffffff8008003e68
        [   58.040263] x23: 0000000000000000 x22: 0000000000000000
        [   58.045587] x21: 0000000000000000 x20: ffffffc68fac1808
        [   58.050910] x19: 0000000000000100 x18: 0000000000000000
        [   58.056232] x17: 0000007f885aff8c x16: 0000007f883a9f10
        [   58.061556] x15: 0000000000000001 x14: 000000000000006e
        [   58.066878] x13: 0000000000000000 x12: 00000000000000ba
        [   58.072201] x11: ffffffc69ff1db30 x10: 0000000000000020
        [   58.077524] x9 : 8000100008001000 x8 : 0000000000000001
        [   58.082847] x7 : 0000000000000800 x6 : ffffff8008003e70
        [   58.088169] x5 : ffffffc69ff17a28 x4 : 00000000ffff138b
        [   58.093492] x3 : 0000000000000000 x2 : 0000000000000000
        [   58.098814] x1 : 0000000000000000 x0 : 0000000000000000
        ...
        [   58.205800] [<          (null)>]           (null)
        [   58.210521] [<ffffff80080f5298>] expire_timers+0xa0/0x14c
        [   58.215937] [<ffffff80080f542c>] run_timer_softirq+0xe8/0x128
        [   58.221702] [<ffffff8008081120>] __do_softirq+0x298/0x348
        [   58.227118] [<ffffff80080a6304>] irq_exit+0x74/0xbc
        [   58.232009] [<ffffff80080e17dc>] __handle_domain_irq+0x78/0xac
        [   58.237857] [<ffffff8008080cf4>] gic_handle_irq+0x80/0xac
        ...
      
      The crash happens roughly 125..130ms after the disconnect. This
      correlates with the 'delay' timer that is started on certain USB tx/rx
      errors in the URB completion handler.
      
      The problem is a race of usbnet_stop() with usbnet_start_xmit(). In
      usbnet_stop() we call usbnet_terminate_urbs() to cancel all URBs in
      flight. This only makes sense if no new URBs are submitted
      concurrently, though. But the usbnet_start_xmit() can run at the same
      time on another CPU which almost unconditionally submits an URB. The
      error callback of the new URB will then schedule the timer after it was
      already stopped.
      
      The fix adds a check if the tx queue is stopped after the tx list lock
      has been taken. This should reliably prevent the submission of new URBs
      while usbnet_terminate_urbs() does its job. The same thing is done on
      the rx side even though it might be safe due to other flags that are
      checked there.
      Signed-off-by: NJan Klötzke <Jan.Kloetzke@preh.de>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      b650ff54
  2. 13 6月, 2018 1 次提交
    • K
      treewide: kmalloc() -> kmalloc_array() · 6da2ec56
      Kees Cook 提交于
      The kmalloc() function has a 2-factor argument form, kmalloc_array(). This
      patch replaces cases of:
      
              kmalloc(a * b, gfp)
      
      with:
              kmalloc_array(a * b, gfp)
      
      as well as handling cases of:
      
              kmalloc(a * b * c, gfp)
      
      with:
      
              kmalloc(array3_size(a, b, c), gfp)
      
      as it's slightly less ugly than:
      
              kmalloc_array(array_size(a, b), c, gfp)
      
      This does, however, attempt to ignore constant size factors like:
      
              kmalloc(4 * 1024, gfp)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The tools/ directory was manually excluded, since it has its own
      implementation of kmalloc().
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        kmalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        kmalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        kmalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        kmalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_ID)
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_ID
      +	COUNT_ID, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * COUNT_CONST
      +	COUNT_CONST, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_ID)
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_ID
      +	COUNT_ID, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (COUNT_CONST)
      +	COUNT_CONST, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * COUNT_CONST
      +	COUNT_CONST, sizeof(THING)
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
      - kmalloc
      + kmalloc_array
        (
      -	SIZE * COUNT
      +	COUNT, SIZE
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        kmalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        kmalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        kmalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        kmalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        kmalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products,
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(
      -	(E1) * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * E3
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	(E1) * (E2) * (E3)
      +	array3_size(E1, E2, E3)
        , ...)
      |
        kmalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants,
      // keeping sizeof() as the second factor argument.
      @@
      expression THING, E1, E2;
      type TYPE;
      constant C1, C2, C3;
      @@
      
      (
        kmalloc(sizeof(THING) * C2, ...)
      |
        kmalloc(sizeof(TYPE) * C2, ...)
      |
        kmalloc(C1 * C2 * C3, ...)
      |
        kmalloc(C1 * C2, ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * (E2)
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(TYPE) * E2
      +	E2, sizeof(TYPE)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * (E2)
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	sizeof(THING) * E2
      +	E2, sizeof(THING)
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * E2
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	(E1) * (E2)
      +	E1, E2
        , ...)
      |
      - kmalloc
      + kmalloc_array
        (
      -	E1 * E2
      +	E1, E2
        , ...)
      )
      Signed-off-by: NKees Cook <keescook@chromium.org>
      6da2ec56
  3. 08 3月, 2018 1 次提交
    • E
      net: usbnet: fix potential deadlock on 32bit hosts · 2695578b
      Eric Dumazet 提交于
      Marek reported a LOCKDEP issue occurring on 32bit host,
      that we tracked down to the fact that usbnet could either
      run from soft or hard irqs.
      
      This patch adds u64_stats_update_begin_irqsave() and
      u64_stats_update_end_irqrestore() helpers to solve this case.
      
      [   17.768040] ================================
      [   17.772239] WARNING: inconsistent lock state
      [   17.776511] 4.16.0-rc3-next-20180227-00007-g876c53a7493c #453 Not tainted
      [   17.783329] --------------------------------
      [   17.787580] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
      [   17.793607] swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
      [   17.798751]  (&syncp->seq#5){?.-.}, at: [<9b22e5f0>]
      asix_rx_fixup_internal+0x188/0x288
      [   17.806790] {IN-HARDIRQ-W} state was registered at:
      [   17.811677]   tx_complete+0x100/0x208
      [   17.815319]   __usb_hcd_giveback_urb+0x60/0xf0
      [   17.819770]   xhci_giveback_urb_in_irq+0xa8/0x240
      [   17.824469]   xhci_td_cleanup+0xf4/0x16c
      [   17.828367]   xhci_irq+0xe74/0x2240
      [   17.831827]   usb_hcd_irq+0x24/0x38
      [   17.835343]   __handle_irq_event_percpu+0x98/0x510
      [   17.840111]   handle_irq_event_percpu+0x1c/0x58
      [   17.844623]   handle_irq_event+0x38/0x5c
      [   17.848519]   handle_fasteoi_irq+0xa4/0x138
      [   17.852681]   generic_handle_irq+0x18/0x28
      [   17.856760]   __handle_domain_irq+0x6c/0xe4
      [   17.860941]   gic_handle_irq+0x54/0xa0
      [   17.864666]   __irq_svc+0x70/0xb0
      [   17.867964]   arch_cpu_idle+0x20/0x3c
      [   17.871578]   arch_cpu_idle+0x20/0x3c
      [   17.875190]   do_idle+0x144/0x218
      [   17.878468]   cpu_startup_entry+0x18/0x1c
      [   17.882454]   start_kernel+0x394/0x400
      [   17.886177] irq event stamp: 161912
      [   17.889616] hardirqs last  enabled at (161912): [<7bedfacf>]
      __netdev_alloc_skb+0xcc/0x140
      [   17.897893] hardirqs last disabled at (161911): [<d58261d0>]
      __netdev_alloc_skb+0x94/0x140
      [   17.904903] exynos5-hsi2c 12ca0000.i2c: tx timeout
      [   17.906116] softirqs last  enabled at (161904): [<387102ff>]
      irq_enter+0x78/0x80
      [   17.906123] softirqs last disabled at (161905): [<cf4c628e>]
      irq_exit+0x134/0x158
      [   17.925722].
      [   17.925722] other info that might help us debug this:
      [   17.933435]  Possible unsafe locking scenario:
      [   17.933435].
      [   17.940331]        CPU0
      [   17.942488]        ----
      [   17.944894]   lock(&syncp->seq#5);
      [   17.948274]   <Interrupt>
      [   17.950847]     lock(&syncp->seq#5);
      [   17.954386].
      [   17.954386]  *** DEADLOCK ***
      [   17.954386].
      [   17.962422] no locks held by swapper/0/0.
      
      Fixes: c8b5d129 ("net: usbnet: support 64bit stats")
      Signed-off-by: NEric Dumazet <edumazet@google.com>
      Reported-by: NMarek Szyprowski <m.szyprowski@samsung.com>
      Cc: Greg Ungerer <gerg@linux-m68k.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2695578b
  4. 23 1月, 2018 1 次提交
  5. 08 12月, 2017 1 次提交
  6. 18 10月, 2017 1 次提交
    • K
      net/usb/usbnet: Convert timers to use timer_setup() · 2183c1a6
      Kees Cook 提交于
      In preparation for unconditionally passing the struct timer_list pointer to
      all timer callbacks, switch to using the new timer_setup() and from_timer()
      to pass the timer pointer explicitly. Since the callback is called from
      both a timer and a tasklet, adjust the tasklet to pass the timer address
      too. When tasklets have their .data field removed, this can be refactored
      to call a central function after resolving the correct container_of() for a
      separate callback function for timer and tasklet.
      
      Cc: Oliver Neukum <oneukum@suse.com>
      Cc: netdev@vger.kernel.org
      Cc: linux-usb@vger.kernel.org
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Acked-by: NOliver Neukum <oneukum@suse.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2183c1a6
  7. 05 6月, 2017 1 次提交
  8. 07 4月, 2017 2 次提交
    • O
      usbnet: make sure no NULL pointer is passed through · 6c22fce0
      Oliver Neukum 提交于
      Coverity reports:
      
      ** CID 751368:  Null pointer dereferences  (FORWARD_NULL)
      /drivers/net/usb/usbnet.c: 1925 in __usbnet_read_cmd()
      
      ________________________________________________________________________________________________________
      *** CID 751368:  Null pointer dereferences  (FORWARD_NULL)
      /drivers/net/usb/usbnet.c: 1925 in __usbnet_read_cmd()
      1919     EXPORT_SYMBOL(usbnet_link_change);
      1920
      1921     /*-------------------------------------------------------------------------*/
      1922     static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
      1923                                 u16 value, u16 index, void *data, u16 size)
      1924     {
      >>>     CID 751368:  Null pointer dereferences  (FORWARD_NULL)
      >>>     Assigning: "buf" = "NULL".
      1925            void *buf = NULL;
      1926            int err = -ENOMEM;
      1927
      1928            netdev_dbg(dev->net, "usbnet_read_cmd cmd=0x%02x reqtype=%02x"
      1929                       " value=0x%04x index=0x%04x size=%d\n",
      1930                       cmd, reqtype, value, index, size);
      
      ** CID 751370:  Null pointer dereferences  (FORWARD_NULL)
      /drivers/net/usb/usbnet.c: 1952 in __usbnet_write_cmd()
      
      ________________________________________________________________________________________________________
      *** CID 751370:  Null pointer dereferences  (FORWARD_NULL)
      /drivers/net/usb/usbnet.c: 1952 in __usbnet_write_cmd()
      1946     }
      1947
      1948     static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
      1949                                  u16 value, u16 index, const void *data,
      1950                                  u16 size)
      1951     {
      >>>     CID 751370:  Null pointer dereferences  (FORWARD_NULL)
      >>>     Assigning: "buf" = "NULL".
      1952            void *buf = NULL;
      1953            int err = -ENOMEM;
      1954
      1955            netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x"
      1956                       " value=0x%04x index=0x%04x size=%d\n",
      1957                       cmd, reqtype, value, index, size);
      
      ** CID 1325026:  Null pointer dereferences  (FORWARD_NULL)
      /drivers/net/usb/ch9200.c: 143 in control_write()
      
      It is valid to offer commands without a buffer, but then you need a size
      of zero. This should actually be checked.
      Signed-off-by: NOliver Neukum <oneukum@suse.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      6c22fce0
    • F
      net: usbnet: Remove unused driver_name variable · b73b3cde
      Florian Fainelli 提交于
      With GCC 6.3, we can get the following warning:
      
      drivers/net/usb/usbnet.c:85:19: warning: 'driver_name' defined but not
      used [-Wunused-const-variable=]
       static const char driver_name [] = "usbnet";
                         ^~~~~~~~~~~
      Signed-off-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b73b3cde
  9. 04 4月, 2017 1 次提交
    • G
      net: usbnet: support 64bit stats · c8b5d129
      Greg Ungerer 提交于
      Add support for the net stats64 counters to the usbnet core. With that
      in place put the hooks into every usbnet driver to use it.
      
      This is a strait forward addition of 64bit counters for RX and TX packet
      and byte counts. It is done in the same style as for the other net drivers
      that support stats64. Note that the other stats fields remain as 32bit
      sized values (error counts, etc).
      
      The motivation to add this is that it is not particularly difficult to
      get the RX and TX byte counts to wrap on 32bit platforms.
      Signed-off-by: NGreg Ungerer <gerg@linux-m68k.org>
      Acked-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c8b5d129
  10. 22 3月, 2017 2 次提交
  11. 21 10月, 2016 1 次提交
    • J
      net: use core MTU range checking in USB NIC drivers · f77f0aee
      Jarod Wilson 提交于
      usbnet:
      - Remove stale new_mtu <= 0 check in usbnet.c
      - Set min_mtu = 0, max_mtu = 65535 (sub-drivers must set their own
        max_mtu and/or min_mtu as needed)
      
      r8152:
      - Set appropriate max_mtu for different variants (1500 or 9194)
      
      lan78xx:
      - Set max_mtu = 9000
      
      asix_driver:
      - max_mtu = 16384 for ax88178 variant
      
      ax88179:
      - max_mtu = 4088
      
      cdc_ncm:
      - max_mtu from hardware
      
      cdc-phonet:
      - min_mtu = 6, max_mtu = 65541
      
      sierra_net:
      - max_mtu = 1500, call usbnet_change_mtu directly
      - sierra_net_change_mtu checked for MTU > 1500, then called
        usbnet_change_mtu, but if we set max_mtu to let the network core handle
        the range check, then we can simply call usbnet_change_mtu directly
      
      smsc75xx:
      - max_mtu = 9000
      
      CC: netdev@vger.kernel.org
      CC: Woojung Huh <woojung.huh@microchip.com>
      CC: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
      CC: Hayes Wang <hayeswang@realtek.com>
      CC: Oliver Neukum <oneukum@suse.com>
      CC: Steve Glendinning <steve.glendinning@shawell.net>
      Signed-off-by: NJarod Wilson <jarod@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f77f0aee
  12. 14 8月, 2016 1 次提交
  13. 18 7月, 2016 1 次提交
  14. 30 6月, 2016 1 次提交
  15. 05 5月, 2016 1 次提交
  16. 04 5月, 2016 1 次提交
  17. 08 3月, 2016 1 次提交
  18. 05 12月, 2015 1 次提交
  19. 11 11月, 2015 1 次提交
  20. 16 9月, 2015 1 次提交
  21. 09 9月, 2015 1 次提交
    • E
      usbnet: Fix a race between usbnet_stop() and the BH · fcb0bb6a
      Eugene Shatokhin 提交于
      The race may happen when a device (e.g. YOTA 4G LTE Modem) is
      unplugged while the system is downloading a large file from the Net.
      
      Hardware breakpoints and Kprobes with delays were used to confirm that
      the race does actually happen.
      
      The race is on skb_queue ('next' pointer) between usbnet_stop()
      and rx_complete(), which, in turn, calls usbnet_bh().
      
      Here is a part of the call stack with the code where the changes to the
      queue happen. The line numbers are for the kernel 4.1.0:
      
      *0 __skb_unlink (skbuff.h:1517)
          prev->next = next;
      *1 defer_bh (usbnet.c:430)
          spin_lock_irqsave(&list->lock, flags);
          old_state = entry->state;
          entry->state = state;
          __skb_unlink(skb, list);
          spin_unlock(&list->lock);
          spin_lock(&dev->done.lock);
          __skb_queue_tail(&dev->done, skb);
          if (dev->done.qlen == 1)
              tasklet_schedule(&dev->bh);
          spin_unlock_irqrestore(&dev->done.lock, flags);
      *2 rx_complete (usbnet.c:640)
          state = defer_bh(dev, skb, &dev->rxq, state);
      
      At the same time, the following code repeatedly checks if the queue is
      empty and reads these values concurrently with the above changes:
      
      *0  usbnet_terminate_urbs (usbnet.c:765)
          /* maybe wait for deletions to finish. */
          while (!skb_queue_empty(&dev->rxq)
              && !skb_queue_empty(&dev->txq)
              && !skb_queue_empty(&dev->done)) {
                  schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS));
                  set_current_state(TASK_UNINTERRUPTIBLE);
                  netif_dbg(dev, ifdown, dev->net,
                        "waited for %d urb completions\n", temp);
          }
      *1  usbnet_stop (usbnet.c:806)
          if (!(info->flags & FLAG_AVOID_UNLINK_URBS))
              usbnet_terminate_urbs(dev);
      
      As a result, it is possible, for example, that the skb is removed from
      dev->rxq by __skb_unlink() before the check
      "!skb_queue_empty(&dev->rxq)" in usbnet_terminate_urbs() is made. It is
      also possible in this case that the skb is added to dev->done queue
      after "!skb_queue_empty(&dev->done)" is checked. So
      usbnet_terminate_urbs() may stop waiting and return while dev->done
      queue still has an item.
      
      Locking in defer_bh() and usbnet_terminate_urbs() was revisited to avoid
      this race.
      Signed-off-by: NEugene Shatokhin <eugene.shatokhin@rosalab.ru>
      Reviewed-by: NBjørn Mork <bjorn@mork.no>
      Acked-by: NOliver Neukum <oneukum@suse.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      fcb0bb6a
  22. 26 8月, 2015 1 次提交
  23. 10 5月, 2015 1 次提交
  24. 10 4月, 2015 1 次提交
  25. 30 3月, 2015 2 次提交
  26. 01 3月, 2015 1 次提交
  27. 25 1月, 2015 1 次提交
  28. 29 10月, 2014 1 次提交
  29. 24 9月, 2014 1 次提交
  30. 03 8月, 2014 1 次提交
  31. 30 7月, 2014 2 次提交
  32. 28 3月, 2014 1 次提交
    • O
      usbnet: include wait queue head in device structure · 14a0d635
      Oliver Neukum 提交于
      This fixes a race which happens by freeing an object on the stack.
      Quoting Julius:
      > The issue is
      > that it calls usbnet_terminate_urbs() before that, which temporarily
      > installs a waitqueue in dev->wait in order to be able to wait on the
      > tasklet to run and finish up some queues. The waiting itself looks
      > okay, but the access to 'dev->wait' is totally unprotected and can
      > race arbitrarily. I think in this case usbnet_bh() managed to succeed
      > it's dev->wait check just before usbnet_terminate_urbs() sets it back
      > to NULL. The latter then finishes and the waitqueue_t structure on its
      > stack gets overwritten by other functions halfway through the
      > wake_up() call in usbnet_bh().
      
      The fix is to just not allocate the data structure on the stack.
      As dev->wait is abused as a flag it also takes a runtime PM change
      to fix this bug.
      Signed-off-by: NOliver Neukum <oneukum@suse.de>
      Reported-by: NGrant Grundler <grundler@google.com>
      Tested-by: NGrant Grundler <grundler@google.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      14a0d635
  33. 18 2月, 2014 1 次提交
    • E
      usbnet: remove generic hard_header_len check · eb85569f
      Emil Goode 提交于
      This patch removes a generic hard_header_len check from the usbnet
      module that is causing dropped packages under certain circumstances
      for devices that send rx packets that cross urb boundaries.
      
      One example is the AX88772B which occasionally send rx packets that
      cross urb boundaries where the remaining partial packet is sent with
      no hardware header. When the buffer with a partial packet is of less
      number of octets than the value of hard_header_len the buffer is
      discarded by the usbnet module.
      
      With AX88772B this can be reproduced by using ping with a packet
      size between 1965-1976.
      
      The bug has been reported here:
      
      https://bugzilla.kernel.org/show_bug.cgi?id=29082
      
      This patch introduces the following changes:
      - Removes the generic hard_header_len check in the rx_complete
        function in the usbnet module.
      - Introduces a ETH_HLEN check for skbs that are not cloned from
        within a rx_fixup callback.
      - For safety a hard_header_len check is added to each rx_fixup
        callback function that could be affected by this change.
        These extra checks could possibly be removed by someone
        who has the hardware to test.
      - Removes a call to dev_kfree_skb_any() and instead utilizes the
        dev->done list to queue skbs for cleanup.
      
      The changes place full responsibility on the rx_fixup callback
      functions that clone skbs to only pass valid skbs to the
      usbnet_skb_return function.
      Signed-off-by: NEmil Goode <emilgoode@gmail.com>
      Reported-by: NIgor Gnatenko <i.gnatenko.brain@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      eb85569f
  34. 14 1月, 2014 1 次提交
  35. 07 12月, 2013 1 次提交