1. 06 1月, 2021 1 次提交
    • J
      net: cdc_ncm: correct overhead in delayed_ndp_size · 7a68d725
      Jouni K. Seppänen 提交于
      Aligning to tx_ndp_modulus is not sufficient because the next align
      call can be cdc_ncm_align_tail, which can add up to ctx->tx_modulus +
      ctx->tx_remainder - 1 bytes. This used to lead to occasional crashes
      on a Huawei 909s-120 LTE module as follows:
      
      - the condition marked /* if there is a remaining skb [...] */ is true
        so the swaps happen
      - skb_out is set from ctx->tx_curr_skb
      - skb_out->len is exactly 0x3f52
      - ctx->tx_curr_size is 0x4000 and delayed_ndp_size is 0xac
        (note that the sum of skb_out->len and delayed_ndp_size is 0x3ffe)
      - the for loop over n is executed once
      - the cdc_ncm_align_tail call marked /* align beginning of next frame */
        increases skb_out->len to 0x3f56 (the sum is now 0x4002)
      - the condition marked /* check if we had enough room left [...] */ is
        false so we break out of the loop
      - the condition marked /* If requested, put NDP at end of frame. */ is
        true so the NDP is written into skb_out
      - now skb_out->len is 0x4002, so padding_count is minus two interpreted
        as an unsigned number, which is used as the length argument to memset,
        leading to a crash with various symptoms but usually including
      
      > Call Trace:
      >  <IRQ>
      >  cdc_ncm_fill_tx_frame+0x83a/0x970 [cdc_ncm]
      >  cdc_mbim_tx_fixup+0x1d9/0x240 [cdc_mbim]
      >  usbnet_start_xmit+0x5d/0x720 [usbnet]
      
      The cdc_ncm_align_tail call first aligns on a ctx->tx_modulus
      boundary (adding at most ctx->tx_modulus-1 bytes), then adds
      ctx->tx_remainder bytes. Alternatively, the next alignment call can
      occur in cdc_ncm_ndp16 or cdc_ncm_ndp32, in which case at most
      ctx->tx_ndp_modulus-1 bytes are added.
      
      A similar problem has occurred before, and the code is nontrivial to
      reason about, so add a guard before the crashing call. By that time it
      is too late to prevent any memory corruption (we'll have written past
      the end of the buffer already) but we can at least try to get a warning
      written into an on-disk log by avoiding the hard crash caused by padding
      past the buffer with a huge number of zeros.
      Signed-off-by: NJouni K. Seppänen <jks@iki.fi>
      Fixes: 4a0e3e98 ("cdc_ncm: Add support for moving NDP to end of NCM frame")
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=209407Reported-by: Nkernel test robot <lkp@intel.com>
      Reviewed-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      7a68d725
  2. 29 12月, 2020 1 次提交
  3. 13 11月, 2020 1 次提交
  4. 08 11月, 2020 1 次提交
  5. 18 7月, 2020 2 次提交
  6. 15 3月, 2020 1 次提交
  7. 12 3月, 2020 1 次提交
    • A
      cdc_ncm: Implement the 32-bit version of NCM Transfer Block · 0fa81b30
      Alexander Bersenev 提交于
      The NCM specification defines two formats of transfer blocks: with 16-bit
      fields (NTB-16) and with 32-bit fields (NTB-32). Currently only NTB-16 is
      implemented.
      
      This patch adds the support of NTB-32. The motivation behind this is that
      some devices such as E5785 or E5885 from the current generation of Huawei
      LTE routers do not support NTB-16. The previous generations of Huawei
      devices are also use NTB-32 by default.
      
      Also this patch enables NTB-32 by default for Huawei devices.
      
      During the 2019 ValdikSS made five attempts to contact Huawei to add the
      NTB-16 support to their router firmware, but they were unsuccessful.
      Signed-off-by: NAlexander Bersenev <bay@hackerdom.ru>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0fa81b30
  8. 14 11月, 2019 1 次提交
  9. 08 11月, 2019 1 次提交
  10. 22 9月, 2019 1 次提交
  11. 13 10月, 2018 1 次提交
  12. 12 10月, 2018 1 次提交
  13. 20 6月, 2018 1 次提交
  14. 09 6月, 2018 1 次提交
    • B
      cdc_ncm: avoid padding beyond end of skb · 49c2c3f2
      Bjørn Mork 提交于
      Commit 4a0e3e98 ("cdc_ncm: Add support for moving NDP to end
      of NCM frame") added logic to reserve space for the NDP at the
      end of the NTB/skb.  This reservation did not take the final
      alignment of the NDP into account, causing us to reserve too
      little space. Additionally the padding prior to NDP addition did
      not ensure there was enough space for the NDP.
      
      The NTB/skb with the NDP appended would then exceed the configured
      max size. This caused the final padding of the NTB to use a
      negative count, padding to almost INT_MAX, and resulting in:
      
      [60103.825970] BUG: unable to handle kernel paging request at ffff9641f2004000
      [60103.825998] IP: __memset+0x24/0x30
      [60103.826001] PGD a6a06067 P4D a6a06067 PUD 4f65a063 PMD 72003063 PTE 0
      [60103.826013] Oops: 0002 [#1] SMP NOPTI
      [60103.826018] Modules linked in: (removed(
      [60103.826158] CPU: 0 PID: 5990 Comm: Chrome_DevTools Tainted: G           O 4.14.0-3-amd64 #1 Debian 4.14.17-1
      [60103.826162] Hardware name: LENOVO 20081 BIOS 41CN28WW(V2.04) 05/03/2012
      [60103.826166] task: ffff964193484fc0 task.stack: ffffb2890137c000
      [60103.826171] RIP: 0010:__memset+0x24/0x30
      [60103.826174] RSP: 0000:ffff964316c03b68 EFLAGS: 00010216
      [60103.826178] RAX: 0000000000000000 RBX: 00000000fffffffd RCX: 000000001ffa5000
      [60103.826181] RDX: 0000000000000005 RSI: 0000000000000000 RDI: ffff9641f2003ffc
      [60103.826184] RBP: ffff964192f6c800 R08: 00000000304d434e R09: ffff9641f1d2c004
      [60103.826187] R10: 0000000000000002 R11: 00000000000005ae R12: ffff9642e6957a80
      [60103.826190] R13: ffff964282ff2ee8 R14: 000000000000000d R15: ffff9642e4843900
      [60103.826194] FS:  00007f395aaf6700(0000) GS:ffff964316c00000(0000) knlGS:0000000000000000
      [60103.826197] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [60103.826200] CR2: ffff9641f2004000 CR3: 0000000013b0c000 CR4: 00000000000006f0
      [60103.826204] Call Trace:
      [60103.826212]  <IRQ>
      [60103.826225]  cdc_ncm_fill_tx_frame+0x5e3/0x740 [cdc_ncm]
      [60103.826236]  cdc_ncm_tx_fixup+0x57/0x70 [cdc_ncm]
      [60103.826246]  usbnet_start_xmit+0x5d/0x710 [usbnet]
      [60103.826254]  ? netif_skb_features+0x119/0x250
      [60103.826259]  dev_hard_start_xmit+0xa1/0x200
      [60103.826267]  sch_direct_xmit+0xf2/0x1b0
      [60103.826273]  __dev_queue_xmit+0x5e3/0x7c0
      [60103.826280]  ? ip_finish_output2+0x263/0x3c0
      [60103.826284]  ip_finish_output2+0x263/0x3c0
      [60103.826289]  ? ip_output+0x6c/0xe0
      [60103.826293]  ip_output+0x6c/0xe0
      [60103.826298]  ? ip_forward_options+0x1a0/0x1a0
      [60103.826303]  tcp_transmit_skb+0x516/0x9b0
      [60103.826309]  tcp_write_xmit+0x1aa/0xee0
      [60103.826313]  ? sch_direct_xmit+0x71/0x1b0
      [60103.826318]  tcp_tasklet_func+0x177/0x180
      [60103.826325]  tasklet_action+0x5f/0x110
      [60103.826332]  __do_softirq+0xde/0x2b3
      [60103.826337]  irq_exit+0xae/0xb0
      [60103.826342]  do_IRQ+0x81/0xd0
      [60103.826347]  common_interrupt+0x98/0x98
      [60103.826351]  </IRQ>
      [60103.826355] RIP: 0033:0x7f397bdf2282
      [60103.826358] RSP: 002b:00007f395aaf57d8 EFLAGS: 00000206 ORIG_RAX: ffffffffffffff6e
      [60103.826362] RAX: 0000000000000000 RBX: 00002f07bc6d0900 RCX: 00007f39752d7fe7
      [60103.826365] RDX: 0000000000000022 RSI: 0000000000000147 RDI: 00002f07baea02c0
      [60103.826368] RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
      [60103.826371] R10: 00000000ffffffff R11: 0000000000000000 R12: 00002f07baea02c0
      [60103.826373] R13: 00002f07bba227a0 R14: 00002f07bc6d090c R15: 0000000000000000
      [60103.826377] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 49 89 f9 48 89 d1 83
      e2 07 48 c1 e9 03 40 0f b6 f6 48 b8 01 01 01 01 01 01 01 01 48 0f af c6 <f3> 48
      ab 89 d1 f3 aa 4c 89 c8 c3 90 49 89 f9 40 88 f0 48 89 d1
      [60103.826442] RIP: __memset+0x24/0x30 RSP: ffff964316c03b68
      [60103.826444] CR2: ffff9641f2004000
      
      Commit e1069bbf ("net: cdc_ncm: Reduce memory use when kernel
      memory low") made this bug much more likely to trigger by reducing
      the NTB size under memory pressure.
      
      Link: https://bugs.debian.org/893393Reported-by: NГорбешко Богдан <bodqhrohro@gmail.com>
      Reported-and-tested-by: NDennis Wassenberg <dennis.wassenberg@secunet.com>
      Cc: Enrico Mioso <mrkiko.rs@gmail.com>
      Fixes: 4a0e3e98 ("cdc_ncm: Add support for moving NDP to end of NCM frame")
      Signed-off-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      49c2c3f2
  15. 27 3月, 2018 1 次提交
  16. 15 11月, 2017 1 次提交
  17. 29 8月, 2017 1 次提交
  18. 19 7月, 2017 1 次提交
  19. 14 7月, 2017 1 次提交
  20. 03 7月, 2017 1 次提交
    • J
      net: cdc_ncm: Reduce memory use when kernel memory low · e1069bbf
      Jim Baxter 提交于
      The CDC-NCM driver can require large amounts of memory to create
      skb's and this can be a problem when the memory becomes fragmented.
      
      This especially affects embedded systems that have constrained
      resources but wish to maximise the throughput of CDC-NCM with 16KiB
      NTB's.
      
      The issue is after running for a while the kernel memory can become
      fragmented and it needs compacting.
      If the NTB allocation is needed before the memory has been compacted
      the atomic allocation can fail which can cause increased latency,
      large re-transmissions or disconnections depending upon the data
      being transmitted at the time.
      This situation occurs for less than a second until the kernel has
      compacted the memory but the failed devices can take a lot longer to
      recover from the failed TX packets.
      
      To ease this temporary situation I modified the CDC-NCM TX path to
      temporarily switch into a reduced memory mode which allocates an NTB
      that will fit into a USB_CDC_NCM_NTB_MIN_OUT_SIZE (default 2048 Bytes)
      sized memory block and only transmit NTB's with a single network frame
      until the memory situation is resolved.
      Each time this issue occurs we wait for an increasing number of
      reduced size allocations before requesting a full size one to not
      put additional pressure on a low memory system.
      
      Once the memory is compacted the CDC-NCM data can resume transmitting
      at the normal tx_max rate once again.
      Signed-off-by: NJim Baxter <jim_baxter@mentor.com>
      Reviewed-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e1069bbf
  21. 21 6月, 2017 1 次提交
    • Y
      net: replace more place to skb_put_[data:zero] · ad941e69
      yuan linyu 提交于
      spatch file,
      @@
      expression skb, len, data;
      type t;
      @@
      -memcpy((t *)skb_put(skb, len), data, len);
      +skb_put_data(skb, data, len);
      
      @@
      identifier p;
      expression skb, len, data;
      type t;
      @@
      -p = (t *)memset(skb_put(skb, len), data, len);
      +p = skb_put_zero(skb, len);
      
      @@
      expression skb, len, data;
      type t;
      @@
      -memcpy((t *)__skb_put(skb, len), data, len);
      +__skb_put_data(skb, data, len);
      
      @@
      identifier p;
      expression skb, len, data;
      type t;
      @@
      -p = (t *)memset(__skb_put(skb, len), data, len);
      +p = __skb_put_zero(skb, len);
      Signed-off-by: Nyuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ad941e69
  22. 16 6月, 2017 4 次提交
    • J
      networking: add and use skb_put_u8() · 634fef61
      Johannes Berg 提交于
      Joe and Bjørn suggested that it'd be nicer to not have the
      cast in the fairly common case of doing
      	*(u8 *)skb_put(skb, 1) = c;
      
      Add skb_put_u8() for this case, and use it across the code,
      using the following spatch:
      
          @@
          expression SKB, C, S;
          typedef u8;
          identifier fn = {skb_put};
          fresh identifier fn2 = fn ## "_u8";
          @@
          - *(u8 *)fn(SKB, S) = C;
          + fn2(SKB, C);
      
      Note that due to the "S", the spatch isn't perfect, it should
      have checked that S is 1, but there's also places that use a
      sizeof expression like sizeof(var) or sizeof(u8) etc. Turns
      out that nobody ever did something like
      	*(u8 *)skb_put(skb, 2) = c;
      
      which would be wrong anyway since the second byte wouldn't be
      initialized.
      Suggested-by: NJoe Perches <joe@perches.com>
      Suggested-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      634fef61
    • J
      networking: make skb_put & friends return void pointers · 4df864c1
      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 (skb_put, __skb_put and pskb_put) 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_put, __skb_put };
          @@
          - *(fn(SKB, LEN))
          + *(u8 *)fn(SKB, LEN)
      
          @@
          expression E, SKB, LEN;
          identifier fn = { skb_put, __skb_put };
          type T;
          @@
          - E = ((T *)(fn(SKB, LEN)))
          + E = fn(SKB, LEN)
      
      which actually doesn't cover pskb_put since there are only three
      users overall.
      
      A handful of stragglers were converted manually, notably a macro in
      drivers/isdn/i4l/isdn_bsdcomp.c and, oddly enough, one of the many
      instances in net/bluetooth/hci_sock.c. In the former file, I also
      had to fix one whitespace problem spatch introduced.
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4df864c1
    • J
      networking: introduce and use skb_put_data() · 59ae1d12
      Johannes Berg 提交于
      A common pattern with skb_put() is to just want to memcpy()
      some data into the new space, introduce skb_put_data() for
      this.
      
      An spatch similar to the one for skb_put_zero() converts many
      of the places using it:
      
          @@
          identifier p, p2;
          expression len, skb, data;
          type t, t2;
          @@
          (
          -p = skb_put(skb, len);
          +p = skb_put_data(skb, data, len);
          |
          -p = (t)skb_put(skb, len);
          +p = skb_put_data(skb, data, len);
          )
          (
          p2 = (t2)p;
          -memcpy(p2, data, len);
          |
          -memcpy(p, data, len);
          )
      
          @@
          type t, t2;
          identifier p, p2;
          expression skb, data;
          @@
          t *p;
          ...
          (
          -p = skb_put(skb, sizeof(t));
          +p = skb_put_data(skb, data, sizeof(t));
          |
          -p = (t *)skb_put(skb, sizeof(t));
          +p = skb_put_data(skb, data, sizeof(t));
          )
          (
          p2 = (t2)p;
          -memcpy(p2, data, sizeof(*p));
          |
          -memcpy(p, data, sizeof(*p));
          )
      
          @@
          expression skb, len, data;
          @@
          -memcpy(skb_put(skb, len), data, len);
          +skb_put_data(skb, data, len);
      
      (again, manually post-processed to retain some comments)
      Reviewed-by: NStephen Hemminger <stephen@networkplumber.org>
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      59ae1d12
    • J
      networking: convert many more places to skb_put_zero() · b080db58
      Johannes Berg 提交于
      There were many places that my previous spatch didn't find,
      as pointed out by yuan linyu in various patches.
      
      The following spatch found many more and also removes the
      now unnecessary casts:
      
          @@
          identifier p, p2;
          expression len;
          expression skb;
          type t, t2;
          @@
          (
          -p = skb_put(skb, len);
          +p = skb_put_zero(skb, len);
          |
          -p = (t)skb_put(skb, len);
          +p = skb_put_zero(skb, len);
          )
          ... when != p
          (
          p2 = (t2)p;
          -memset(p2, 0, len);
          |
          -memset(p, 0, len);
          )
      
          @@
          type t, t2;
          identifier p, p2;
          expression skb;
          @@
          t *p;
          ...
          (
          -p = skb_put(skb, sizeof(t));
          +p = skb_put_zero(skb, sizeof(t));
          |
          -p = (t *)skb_put(skb, sizeof(t));
          +p = skb_put_zero(skb, sizeof(t));
          )
          ... when != p
          (
          p2 = (t2)p;
          -memset(p2, 0, sizeof(*p));
          |
          -memset(p, 0, sizeof(*p));
          )
      
          @@
          expression skb, len;
          @@
          -memset(skb_put(skb, len), 0, len);
          +skb_put_zero(skb, len);
      
      Apply it to the tree (with one manual fixup to keep the
      comment in vxlan.c, which spatch removed.)
      Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b080db58
  23. 09 5月, 2017 1 次提交
  24. 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
  25. 22 3月, 2017 1 次提交
  26. 26 12月, 2016 1 次提交
    • T
      ktime: Cleanup ktime_set() usage · 8b0e1953
      Thomas Gleixner 提交于
      ktime_set(S,N) was required for the timespec storage type and is still
      useful for situations where a Seconds and Nanoseconds part of a time value
      needs to be converted. For anything where the Seconds argument is 0, this
      is pointless and can be replaced with a simple assignment.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      8b0e1953
  27. 09 12月, 2016 1 次提交
  28. 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
  29. 05 7月, 2016 1 次提交
  30. 21 5月, 2016 1 次提交
  31. 01 4月, 2016 1 次提交
  32. 08 3月, 2016 2 次提交
  33. 24 12月, 2015 1 次提交
    • B
      net: cdc_ncm: avoid changing RX/TX buffers on MTU changes · 1dfddff5
      Bjørn Mork 提交于
      NCM buffer sizes are negotiated with the device independently of
      the network device MTU.  The RX buffers are allocated by the
      usbnet framework based on the rx_urb_size value set by cdc_ncm. A
      single RX buffer can hold a number of MTU sized packets.
      
      The default usbnet change_mtu ndo only modifies rx_urb_size if it
      is equal to hard_mtu.  And the cdc_ncm driver will set rx_urb_size
      and hard_mtu independently of each other, based on dwNtbInMaxSize
      and dwNtbOutMaxSize respectively. It was therefore assumed that
      usbnet_change_mtu() would never touch rx_urb_size.  This failed to
      consider the case where dwNtbInMaxSize and dwNtbOutMaxSize happens
      to be equal.
      
      Fix by implementing an NCM specific change_mtu ndo, modifying the
      netdev MTU without touching the buffer size settings.
      Signed-off-by: NBjørn Mork <bjorn@mork.no>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1dfddff5
  34. 22 12月, 2015 2 次提交