1. 21 Feb, 2024 2 commits
    • Erick Archer's avatar
      RDMA/uverbs: Remove flexible arrays from struct *_filter · 14b526f5
      Erick Archer authored
      When a struct containing a flexible array is included in another struct,
      and there is a member after the struct-with-flex-array, there is a
      possibility of memory overlap. These cases must be audited [1]. See:
      
      struct inner {
      	...
      	int flex[];
      };
      
      struct outer {
      	...
      	struct inner header;
      	int overlap;
      	...
      };
      
      This is the scenario for all the "struct *_filter" structures that are
      included in the following "struct ib_flow_spec_*" structures:
      
      struct ib_flow_spec_eth
      struct ib_flow_spec_ib
      struct ib_flow_spec_ipv4
      struct ib_flow_spec_ipv6
      struct ib_flow_spec_tcp_udp
      struct ib_flow_spec_tunnel
      struct ib_flow_spec_esp
      struct ib_flow_spec_gre
      struct ib_flow_spec_mpls
      
      The pattern is like the one shown below:
      
      struct *_filter {
      	...
      	u8 real_sz[];
      };
      
      struct ib_flow_spec_* {
      	...
      	struct *_filter val;
      	struct *_filter mask;
      };
      
      In this case, the trailing flexible array "real_sz" is never allocated
      and is only used to calculate the size of the structures. Here the use
      of the "offsetof" helper can be changed by the "sizeof" operator because
      the goal is to get the size of these structures. Therefore, the trailing
      flexible arrays can also be removed.
      
      However, due to the trailing padding that can be induced in structs it
      is possible that the:
      
      offsetof(struct *_filter, real_sz) != sizeof(struct *_filter)
      
      This situation happens with the "struct ib_flow_ipv6_filter" and to
      avoid it the "__packed" macro is used in this structure. But now, the
      "sizeof(struct ib_flow_ipv6_filter)" has changed. This is not a problem
      since this size is not used in the code.
      
      The situation now is that "sizeof(struct ib_flow_spec_ipv6)" has also
      changed (this struct contains the struct ib_flow_ipv6_filter). This is
      also not a problem since it is only used to set the size of the "union
      ib_flow_spec", which can store all the "ib_flow_spec_*" structures.
      
      Link: https://lore.kernel.org/r/20240217142913.4285-1-erick.archer@gmx.comSigned-off-by: default avatarErick Archer <erick.archer@gmx.com>
      Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
      14b526f5
    • Shifeng Li's avatar
      RDMA/device: Fix a race between mad_client and cm_client init · 7a8bccd8
      Shifeng Li authored
      The mad_client will be initialized in enable_device_and_get(), while the
      devices_rwsem will be downgraded to a read semaphore. There is a window
      that leads to the failed initialization for cm_client, since it can not
      get matched mad port from ib_mad_port_list, and the matched mad port will
      be added to the list after that.
      
          mad_client    |                       cm_client
      ------------------|--------------------------------------------------------
      ib_register_device|
      enable_device_and_get
      down_write(&devices_rwsem)
      xa_set_mark(&devices, DEVICE_REGISTERED)
      downgrade_write(&devices_rwsem)
                        |
                        |ib_cm_init
                        |ib_register_client(&cm_client)
                        |down_read(&devices_rwsem)
                        |xa_for_each_marked (&devices, DEVICE_REGISTERED)
                        |add_client_context
                        |cm_add_one
                        |ib_register_mad_agent
                        |ib_get_mad_port
                        |__ib_get_mad_port
                        |list_for_each_entry(entry, &ib_mad_port_list, port_list)
                        |return NULL
                        |up_read(&devices_rwsem)
                        |
      add_client_context|
      ib_mad_init_device|
      ib_mad_port_open  |
      list_add_tail(&port_priv->port_list, &ib_mad_port_list)
      up_read(&devices_rwsem)
                        |
      
      Fix it by using down_write(&devices_rwsem) in ib_register_client().
      
      Fixes: d0899892 ("RDMA/device: Provide APIs from the core code to help unregistration")
      Link: https://lore.kernel.org/r/20240203035313.98991-1-lishifeng@sangfor.com.cnSuggested-by: default avatarJason Gunthorpe <jgg@ziepe.ca>
      Signed-off-by: default avatarShifeng Li <lishifeng@sangfor.com.cn>
      Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
      7a8bccd8
  2. 19 Feb, 2024 1 commit
  3. 04 Feb, 2024 3 commits
  4. 31 Jan, 2024 1 commit
  5. 25 Jan, 2024 15 commits
  6. 21 Jan, 2024 18 commits