1. 31 10月, 2020 5 次提交
    • X
      sctp: allow changing transport encap_port by peer packets · a1dd2cf2
      Xin Long 提交于
      As rfc6951#section-5.4 says:
      
        "After finding the SCTP association (which
         includes checking the verification tag), the UDP source port MUST be
         stored as the encapsulation port for the destination address the SCTP
         packet is received from (see Section 5.1).
      
         When a non-encapsulated SCTP packet is received by the SCTP stack,
         the encapsulation of outgoing packets belonging to the same
         association and the corresponding destination address MUST be
         disabled."
      
      transport encap_port should be updated by a validated incoming packet's
      udp src port.
      
      We save the udp src port in sctp_input_cb->encap_port, and then update
      the transport in two places:
      
        1. right after vtag is verified, which is required by RFC, and this
           allows the existent transports to be updated by the chunks that
           can only be processed on an asoc.
      
        2. right before processing the 'init' where the transports are added,
           and this allows building a sctp over udp connection by client with
           the server not knowing the remote encap port.
      
        3. when processing ootb_pkt and creating the temporary transport for
           the reply pkt.
      
      Note that sctp_input_cb->header is removed, as it's not used any more
      in sctp.
      
      v1->v2:
        - Change encap_port as __be16 for sctp_input_cb.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      a1dd2cf2
    • X
      sctp: add encap_port for netns sock asoc and transport · e8a3001c
      Xin Long 提交于
      encap_port is added as per netns/sock/assoc/transport, and the
      latter one's encap_port inherits the former one's by default.
      The transport's encap_port value would mostly decide if one
      packet should go out with udp encapsulated or not.
      
      This patch also allows users to set netns' encap_port by sysctl.
      
      v1->v2:
        - Change to define encap_port as __be16 for sctp_sock, asoc and
          transport.
      v2->v3:
        - No change.
      v3->v4:
        - Add 'encap_port' entry in ip-sysctl.rst.
      v4->v5:
        - Improve the description of encap_port in ip-sysctl.rst.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      e8a3001c
    • X
      sctp: add encap_err_lookup for udp encap socks · 89ba4917
      Xin Long 提交于
      As it says in rfc6951#section-5.5:
      
        "When receiving ICMP or ICMPv6 response packets, there might not be
         enough bytes in the payload to identify the SCTP association that the
         SCTP packet triggering the ICMP or ICMPv6 packet belongs to.  If a
         received ICMP or ICMPv6 packet cannot be related to a specific SCTP
         association or the verification tag cannot be verified, it MUST be
         discarded silently.  In particular, this means that the SCTP stack
         MUST NOT rely on receiving ICMP or ICMPv6 messages.  Implementation
         constraints could prevent processing received ICMP or ICMPv6
         messages."
      
      ICMP or ICMPv6 packets need to be handled, and this is implemented by
      udp encap sock .encap_err_lookup function.
      
      The .encap_err_lookup function is called in __udp(6)_lib_err_encap()
      to confirm this path does need to be updated. For sctp, what we can
      do here is check if the corresponding asoc and transport exist.
      
      Note that icmp packet process for sctp over udp is done by udp sock
      .encap_err_lookup(), and it means for now we can't do as much as
      sctp_v4/6_err() does. Also we can't do the two mappings mentioned
      in rfc6951#section-5.5.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      89ba4917
    • X
      sctp: create udp6 sock and set its encap_rcv · 9d6ba260
      Xin Long 提交于
      This patch is to add the udp6 sock part in sctp_udp_sock_start/stop().
      udp_conf.use_udp6_rx_checksums is set to true, as:
      
         "The SCTP checksum MUST be computed for IPv4 and IPv6, and the UDP
          checksum SHOULD be computed for IPv4 and IPv6"
      
      says in rfc6951#section-5.3.
      
      v1->v2:
        - Add pr_err() when fails to create udp v6 sock.
        - Add #if IS_ENABLED(CONFIG_IPV6) not to create v6 sock when ipv6 is
          disabled.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      9d6ba260
    • X
      sctp: create udp4 sock and add its encap_rcv · 965ae444
      Xin Long 提交于
      This patch is to add the functions to create/release udp4 sock,
      and set the sock's encap_rcv to process the incoming udp encap
      sctp packets. In sctp_udp_rcv(), as we can see, all we need to
      do is fix the transport header for sctp_rcv(), then it would
      implement the part of rfc6951#section-5.4:
      
        "When an encapsulated packet is received, the UDP header is removed.
         Then, the generic lookup is performed, as done by an SCTP stack
         whenever a packet is received, to find the association for the
         received SCTP packet"
      
      Note that these functions will be called in the last patch of
      this patchset when enabling this feature.
      
      v1->v2:
        - Add pr_err() when fails to create udp v4 sock.
      v2->v3:
        - Add 'select NET_UDP_TUNNEL' in sctp Kconfig.
      v3->v4:
        - No change.
      v4->v5:
        - Change to set udp_port to 0 by default.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      965ae444
  2. 25 8月, 2020 1 次提交
  3. 25 7月, 2020 1 次提交
  4. 20 7月, 2020 2 次提交
  5. 26 6月, 2020 1 次提交
  6. 30 3月, 2020 1 次提交
    • M
      sctp: fix possibly using a bad saddr with a given dst · 582eea23
      Marcelo Ricardo Leitner 提交于
      Under certain circumstances, depending on the order of addresses on the
      interfaces, it could be that sctp_v[46]_get_dst() would return a dst
      with a mismatched struct flowi.
      
      For example, if when walking through the bind addresses and the first
      one is not a match, it saves the dst as a fallback (added in
      410f0383), but not the flowi. Then if the next one is also not a
      match, the previous dst will be returned but with the flowi information
      for the 2nd address, which is wrong.
      
      The fix is to use a locally stored flowi that can be used for such
      attempts, and copy it to the parameter only in case it is a possible
      match, together with the corresponding dst entry.
      
      The patch updates IPv6 code mostly just to be in sync. Even though the issue
      is also present there, it fallback is not expected to work with IPv6.
      
      Fixes: 410f0383 ("sctp: add routing output fallback")
      Reported-by: NJin Meng <meng.a.jin@nokia-sbell.com>
      Signed-off-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Tested-by: NXin Long <lucien.xin@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      582eea23
  7. 10 12月, 2019 1 次提交
    • X
      sctp: fully initialize v4 addr in some functions · b6f3320b
      Xin Long 提交于
      Syzbot found a crash:
      
        BUG: KMSAN: uninit-value in crc32_body lib/crc32.c:112 [inline]
        BUG: KMSAN: uninit-value in crc32_le_generic lib/crc32.c:179 [inline]
        BUG: KMSAN: uninit-value in __crc32c_le_base+0x4fa/0xd30 lib/crc32.c:202
        Call Trace:
          crc32_body lib/crc32.c:112 [inline]
          crc32_le_generic lib/crc32.c:179 [inline]
          __crc32c_le_base+0x4fa/0xd30 lib/crc32.c:202
          chksum_update+0xb2/0x110 crypto/crc32c_generic.c:90
          crypto_shash_update+0x4c5/0x530 crypto/shash.c:107
          crc32c+0x150/0x220 lib/libcrc32c.c:47
          sctp_csum_update+0x89/0xa0 include/net/sctp/checksum.h:36
          __skb_checksum+0x1297/0x12a0 net/core/skbuff.c:2640
          sctp_compute_cksum include/net/sctp/checksum.h:59 [inline]
          sctp_packet_pack net/sctp/output.c:528 [inline]
          sctp_packet_transmit+0x40fb/0x4250 net/sctp/output.c:597
          sctp_outq_flush_transports net/sctp/outqueue.c:1146 [inline]
          sctp_outq_flush+0x1823/0x5d80 net/sctp/outqueue.c:1194
          sctp_outq_uncork+0xd0/0xf0 net/sctp/outqueue.c:757
          sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1781 [inline]
          sctp_side_effects net/sctp/sm_sideeffect.c:1184 [inline]
          sctp_do_sm+0x8fe1/0x9720 net/sctp/sm_sideeffect.c:1155
          sctp_primitive_REQUESTHEARTBEAT+0x175/0x1a0 net/sctp/primitive.c:185
          sctp_apply_peer_addr_params+0x212/0x1d40 net/sctp/socket.c:2433
          sctp_setsockopt_peer_addr_params net/sctp/socket.c:2686 [inline]
          sctp_setsockopt+0x189bb/0x19090 net/sctp/socket.c:4672
      
      The issue was caused by transport->ipaddr set with uninit addr param, which
      was passed by:
      
        sctp_transport_init net/sctp/transport.c:47 [inline]
        sctp_transport_new+0x248/0xa00 net/sctp/transport.c:100
        sctp_assoc_add_peer+0x5ba/0x2030 net/sctp/associola.c:611
        sctp_process_param net/sctp/sm_make_chunk.c:2524 [inline]
      
      where 'addr' is set by sctp_v4_from_addr_param(), and it doesn't initialize
      the padding of addr->v4.
      
      Later when calling sctp_make_heartbeat(), hbinfo.daddr(=transport->ipaddr)
      will become the part of skb, and the issue occurs.
      
      This patch is to fix it by initializing the padding of addr->v4 in
      sctp_v4_from_addr_param(), as well as other functions that do the similar
      thing, and these functions shouldn't trust that the caller initializes the
      memory, as Marcelo suggested.
      
      Reported-by: syzbot+6dcbfea81cd3d4dd0b02@syzkaller.appspotmail.com
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NNeil Horman <nhorman@tuxdriver.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b6f3320b
  8. 09 11月, 2019 2 次提交
    • X
      sctp: add support for Primary Path Switchover · 34515e94
      Xin Long 提交于
      This is a new feature defined in section 5 of rfc7829: "Primary Path
      Switchover". By introducing a new tunable parameter:
      
        Primary.Switchover.Max.Retrans (PSMR)
      
      The primary path will be changed to another active path when the path
      error counter on the old primary path exceeds PSMR, so that "the SCTP
      sender is allowed to continue data transmission on a new working path
      even when the old primary destination address becomes active again".
      
      This patch is to add this tunable parameter, 'ps_retrans' per netns,
      sock, asoc and transport. It also allows a user to change ps_retrans
      per netns by sysctl, and ps_retrans per sock/asoc/transport will be
      initialized with it.
      
      The check will be done in sctp_do_8_2_transport_strike() when this
      feature is enabled.
      
      Note this feature is disabled by initializing 'ps_retrans' per netns
      as 0xffff by default, and its value can't be less than 'pf_retrans'
      when changing by sysctl.
      
      v3->v4:
        - add define SCTP_PS_RETRANS_MAX 0xffff, and use it on extra2 of
          sysctl 'ps_retrans'.
        - add a new entry for ps_retrans on ip-sysctl.txt.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NNeil Horman <nhorman@tuxdriver.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      34515e94
    • X
      sctp: add pf_expose per netns and sock and asoc · aef587be
      Xin Long 提交于
      As said in rfc7829, section 3, point 12:
      
        The SCTP stack SHOULD expose the PF state of its destination
        addresses to the ULP as well as provide the means to notify the
        ULP of state transitions of its destination addresses from
        active to PF, and vice versa.  However, it is recommended that
        an SCTP stack implementing SCTP-PF also allows for the ULP to be
        kept ignorant of the PF state of its destinations and the
        associated state transitions, thus allowing for retention of the
        simpler state transition model of [RFC4960] in the ULP.
      
      Not only does it allow to expose the PF state to ULP, but also
      allow to ignore sctp-pf to ULP.
      
      So this patch is to add pf_expose per netns, sock and asoc. And in
      sctp_assoc_control_transport(), ulp_notify will be set to false if
      asoc->expose is not 'enabled' in next patch.
      
      It also allows a user to change pf_expose per netns by sysctl, and
      pf_expose per sock and asoc will be initialized with it.
      
      Note that pf_expose also works for SCTP_GET_PEER_ADDR_INFO sockopt,
      to not allow a user to query the state of a sctp-pf peer address
      when pf_expose is 'disabled', as said in section 7.3.
      
      v1->v2:
        - Fix a build warning noticed by Nathan Chancellor.
      v2->v3:
        - set pf_expose to UNUSED by default to keep compatible with old
          applications.
      v3->v4:
        - add a new entry for pf_expose on ip-sysctl.txt, as Marcelo suggested.
        - change this patch to 1/5, and move sctp_assoc_control_transport
          change into 2/5, as Marcelo suggested.
        - use SCTP_PF_EXPOSE_UNSET instead of SCTP_PF_EXPOSE_UNUSED, and
          set SCTP_PF_EXPOSE_UNSET to 0 in enum, as Marcelo suggested.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Acked-by: NNeil Horman <nhorman@tuxdriver.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      aef587be
  9. 12 9月, 2019 1 次提交
  10. 28 8月, 2019 1 次提交
  11. 03 6月, 2019 1 次提交
  12. 24 5月, 2019 1 次提交
  13. 20 4月, 2019 1 次提交
  14. 02 4月, 2019 1 次提交
    • X
      sctp: initialize _pad of sockaddr_in before copying to user memory · 09279e61
      Xin Long 提交于
      Syzbot report a kernel-infoleak:
      
        BUG: KMSAN: kernel-infoleak in _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
        Call Trace:
          _copy_to_user+0x16b/0x1f0 lib/usercopy.c:32
          copy_to_user include/linux/uaccess.h:174 [inline]
          sctp_getsockopt_peer_addrs net/sctp/socket.c:5911 [inline]
          sctp_getsockopt+0x1668e/0x17f70 net/sctp/socket.c:7562
          ...
        Uninit was stored to memory at:
          sctp_transport_init net/sctp/transport.c:61 [inline]
          sctp_transport_new+0x16d/0x9a0 net/sctp/transport.c:115
          sctp_assoc_add_peer+0x532/0x1f70 net/sctp/associola.c:637
          sctp_process_param net/sctp/sm_make_chunk.c:2548 [inline]
          sctp_process_init+0x1a1b/0x3ed0 net/sctp/sm_make_chunk.c:2361
          ...
        Bytes 8-15 of 16 are uninitialized
      
      It was caused by that th _pad field (the 8-15 bytes) of a v4 addr (saved in
      struct sockaddr_in) wasn't initialized, but directly copied to user memory
      in sctp_getsockopt_peer_addrs().
      
      So fix it by calling memset(addr->v4.sin_zero, 0, 8) to initialize _pad of
      sockaddr_in before copying it to user memory in sctp_v4_addr_to_user(), as
      sctp_v6_addr_to_user() does.
      
      Reported-by: syzbot+86b5c7c236a22616a72f@syzkaller.appspotmail.com
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Tested-by: NAlexander Potapenko <glider@google.com>
      Acked-by: NNeil Horman <nhorman@tuxdriver.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      09279e61
  15. 25 1月, 2019 1 次提交
    • X
      sctp: set flow sport from saddr only when it's 0 · ecf938fe
      Xin Long 提交于
      Now sctp_transport_pmtu() passes transport->saddr into .get_dst() to set
      flow sport from 'saddr'. However, transport->saddr is set only when
      transport->dst exists in sctp_transport_route().
      
      If sctp_transport_pmtu() is called without transport->saddr set, like
      when transport->dst doesn't exists, the flow sport will be set to 0
      from transport->saddr, which will cause a wrong route to be got.
      
      Commit 6e91b578 ("sctp: re-use sctp_transport_pmtu in
      sctp_transport_route") made the issue be triggered more easily
      since sctp_transport_pmtu() would be called in sctp_transport_route()
      after that.
      
      In gerneral, fl4->fl4_sport should always be set to
      htons(asoc->base.bind_addr.port), unless transport->asoc doesn't exist
      in sctp_v4/6_get_dst(), which is the case:
      
        sctp_ootb_pkt_new() ->
          sctp_transport_route()
      
      For that, we can simply handle it by setting flow sport from saddr only
      when it's 0 in sctp_v4/6_get_dst().
      
      Fixes: 6e91b578 ("sctp: re-use sctp_transport_pmtu in sctp_transport_route")
      Reported-by: NYing Xu <yinxu@redhat.com>
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      ecf938fe
  16. 17 1月, 2019 1 次提交
  17. 29 12月, 2018 2 次提交
  18. 31 10月, 2018 1 次提交
  19. 04 7月, 2018 1 次提交
    • X
      sctp: add support for dscp and flowlabel per transport · 8a9c58d2
      Xin Long 提交于
      Like some other per transport params, flowlabel and dscp are added
      in transport, asoc and sctp_sock. By default, transport sets its
      value from asoc's, and asoc does it from sctp_sock. flowlabel
      only works for ipv6 transport.
      
      Other than that they need to be passed down in sctp_xmit, flow4/6
      also needs to set them before looking up route in get_dst.
      
      Note that it uses '& 0x100000' to check if flowlabel is set and
      '& 0x1' (tos 1st bit is unused) to check if dscp is set by users,
      so that they could be set to 0 by sockopt in next patch.
      Signed-off-by: NXin Long <lucien.xin@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      8a9c58d2
  20. 29 6月, 2018 1 次提交
    • L
      Revert changes to convert to ->poll_mask() and aio IOCB_CMD_POLL · a11e1d43
      Linus Torvalds 提交于
      The poll() changes were not well thought out, and completely
      unexplained.  They also caused a huge performance regression, because
      "->poll()" was no longer a trivial file operation that just called down
      to the underlying file operations, but instead did at least two indirect
      calls.
      
      Indirect calls are sadly slow now with the Spectre mitigation, but the
      performance problem could at least be largely mitigated by changing the
      "->get_poll_head()" operation to just have a per-file-descriptor pointer
      to the poll head instead.  That gets rid of one of the new indirections.
      
      But that doesn't fix the new complexity that is completely unwarranted
      for the regular case.  The (undocumented) reason for the poll() changes
      was some alleged AIO poll race fixing, but we don't make the common case
      slower and more complex for some uncommon special case, so this all
      really needs way more explanations and most likely a fundamental
      redesign.
      
      [ This revert is a revert of about 30 different commits, not reverted
        individually because that would just be unnecessarily messy  - Linus ]
      
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Christoph Hellwig <hch@lst.de>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a11e1d43
  21. 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
  22. 26 5月, 2018 1 次提交
  23. 23 5月, 2018 1 次提交
  24. 30 3月, 2018 1 次提交
  25. 28 3月, 2018 1 次提交
  26. 18 3月, 2018 1 次提交
  27. 13 3月, 2018 2 次提交
  28. 27 2月, 2018 1 次提交
  29. 06 2月, 2018 1 次提交
    • T
      sctp: fix dst refcnt leak in sctp_v4_get_dst · 4a31a6b1
      Tommi Rantala 提交于
      Fix dst reference count leak in sctp_v4_get_dst() introduced in commit
      410f0383 ("sctp: add routing output fallback"):
      
      When walking the address_list, successive ip_route_output_key() calls
      may return the same rt->dst with the reference incremented on each call.
      
      The code would not decrement the dst refcount when the dst pointer was
      identical from the previous iteration, causing the dst refcnt leak.
      
      Testcase:
        ip netns add TEST
        ip netns exec TEST ip link set lo up
        ip link add dummy0 type dummy
        ip link add dummy1 type dummy
        ip link add dummy2 type dummy
        ip link set dev dummy0 netns TEST
        ip link set dev dummy1 netns TEST
        ip link set dev dummy2 netns TEST
        ip netns exec TEST ip addr add 192.168.1.1/24 dev dummy0
        ip netns exec TEST ip link set dummy0 up
        ip netns exec TEST ip addr add 192.168.1.2/24 dev dummy1
        ip netns exec TEST ip link set dummy1 up
        ip netns exec TEST ip addr add 192.168.1.3/24 dev dummy2
        ip netns exec TEST ip link set dummy2 up
        ip netns exec TEST sctp_test -H 192.168.1.2 -P 20002 -h 192.168.1.1 -p 20000 -s -B 192.168.1.3
        ip netns del TEST
      
      In 4.4 and 4.9 kernels this results to:
        [  354.179591] unregister_netdevice: waiting for lo to become free. Usage count = 1
        [  364.419674] unregister_netdevice: waiting for lo to become free. Usage count = 1
        [  374.663664] unregister_netdevice: waiting for lo to become free. Usage count = 1
        [  384.903717] unregister_netdevice: waiting for lo to become free. Usage count = 1
        [  395.143724] unregister_netdevice: waiting for lo to become free. Usage count = 1
        [  405.383645] unregister_netdevice: waiting for lo to become free. Usage count = 1
        ...
      
      Fixes: 410f0383 ("sctp: add routing output fallback")
      Fixes: 0ca50d12 ("sctp: fix src address selection if using secondary addresses")
      Signed-off-by: NTommi Rantala <tommi.t.rantala@nokia.com>
      Acked-by: NMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
      Acked-by: NNeil Horman <nhorman@tuxdriver.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4a31a6b1
  30. 29 11月, 2017 1 次提交
  31. 25 10月, 2017 1 次提交
  32. 07 8月, 2017 1 次提交