Unverified Commit c72878be authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15198 CVE-2024-57857

Merge Pull Request from: @ci-robot 
 
PR sync from: Liu Jian <liujian56@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/FUWQJQTECITNY5TWR5VN2JPJGINNFU3I/ 
CVE-2024-57857

Bernard Metzler (2):
  RDMA/siw: Enable siw on tunnel devices
  RDMA/siw: Remove direct link to net_device

Chuck Lever (1):
  RDMA/siw: Fabricate a GID on tun and loopback devices

Kamal Heib (1):
  RDMA/siw: Use helper function to set sys_image_guid


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IBI67U 
 
Link:https://gitee.com/openeuler/kernel/pulls/15198

 

Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Reviewed-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 0f19fd14 46b6599c
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@
 */
#define SIW_IRQ_MAXBURST_SQ_ACTIVE 4

/* There is always only a port 1 per siw device */
#define SIW_PORT 1

struct siw_dev_cap {
	int max_qp;
	int max_qp_wr;
@@ -69,14 +72,11 @@ struct siw_pd {

struct siw_device {
	struct ib_device base_dev;
	struct net_device *netdev;
	struct siw_dev_cap attrs;

	u32 vendor_part_id;
	int numa_node;

	/* physical port state (only one port per device) */
	enum ib_port_state state;
	char raw_gid[ETH_ALEN];

	spinlock_t lock;

+21 −6
Original line number Diff line number Diff line
@@ -1767,6 +1767,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
{
	struct socket *s;
	struct siw_cep *cep = NULL;
	struct net_device *ndev = NULL;
	struct siw_device *sdev = to_siw_dev(id->device);
	int addr_family = id->local_addr.ss_family;
	int rv = 0;
@@ -1787,18 +1788,30 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
		struct sockaddr_in *laddr = &to_sockaddr_in(id->local_addr);

		/* For wildcard addr, limit binding to current device only */
		if (ipv4_is_zeronet(laddr->sin_addr.s_addr))
			s->sk->sk_bound_dev_if = sdev->netdev->ifindex;

		if (ipv4_is_zeronet(laddr->sin_addr.s_addr)) {
			ndev = ib_device_get_netdev(id->device, SIW_PORT);
			if (ndev) {
				s->sk->sk_bound_dev_if = ndev->ifindex;
			} else {
				rv = -ENODEV;
				goto error;
			}
		}
		rv = s->ops->bind(s, (struct sockaddr *)laddr,
				  sizeof(struct sockaddr_in));
	} else {
		struct sockaddr_in6 *laddr = &to_sockaddr_in6(id->local_addr);

		/* For wildcard addr, limit binding to current device only */
		if (ipv6_addr_any(&laddr->sin6_addr))
			s->sk->sk_bound_dev_if = sdev->netdev->ifindex;

		if (ipv6_addr_any(&laddr->sin6_addr)) {
			ndev = ib_device_get_netdev(id->device, SIW_PORT);
			if (ndev) {
				s->sk->sk_bound_dev_if = ndev->ifindex;
			} else {
				rv = -ENODEV;
				goto error;
			}
		}
		rv = s->ops->bind(s, (struct sockaddr *)laddr,
				  sizeof(struct sockaddr_in6));
	}
@@ -1859,6 +1872,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
	}
	list_add_tail(&cep->listenq, (struct list_head *)id->provider_data);
	cep->state = SIW_EPSTATE_LISTENING;
	dev_put(ndev);

	siw_dbg(id->device, "Listen at laddr %pISp\n", &id->local_addr);

@@ -1882,6 +1896,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
		siw_cep_put(cep);
	}
	sock_release(s);
	dev_put(ndev);

	return rv;
}
+11 −27
Original line number Diff line number Diff line
@@ -75,8 +75,7 @@ static int siw_device_register(struct siw_device *sdev, const char *name)
		return rv;
	}

	siw_dbg(base_dev, "HWaddr=%pM\n", sdev->netdev->dev_addr);

	siw_dbg(base_dev, "HWaddr=%pM\n", sdev->raw_gid);
	return 0;
}

@@ -120,6 +119,7 @@ static int siw_dev_qualified(struct net_device *netdev)
	 * <linux/if_arp.h> for type identifiers.
	 */
	if (netdev->type == ARPHRD_ETHER || netdev->type == ARPHRD_IEEE802 ||
	    netdev->type == ARPHRD_NONE ||
	    (netdev->type == ARPHRD_LOOPBACK && loopback_enabled))
		return 1;

@@ -313,23 +313,18 @@ static struct siw_device *siw_device_create(struct net_device *netdev)

	base_dev = &sdev->base_dev;

	sdev->netdev = netdev;

	if (netdev->type != ARPHRD_LOOPBACK) {
		addrconf_addr_eui48((unsigned char *)&base_dev->node_guid,
				    netdev->dev_addr);
	if (netdev->addr_len) {
		memcpy(sdev->raw_gid, netdev->dev_addr,
		       min_t(unsigned int, netdev->addr_len, ETH_ALEN));
	} else {
		/*
		 * The loopback device does not have a HW address,
		 * but connection mangagement lib expects gid != 0
		 * This device does not have a HW address, but
		 * connection mangagement requires a unique gid.
		 */
		size_t len = min_t(size_t, strlen(base_dev->name), 6);
		char addr[6] = { };

		memcpy(addr, base_dev->name, len);
		addrconf_addr_eui48((unsigned char *)&base_dev->node_guid,
				    addr);
		eth_random_addr(sdev->raw_gid);
	}
	addrconf_addr_eui48((u8 *)&base_dev->node_guid, sdev->raw_gid);

	base_dev->uverbs_cmd_mask =
		(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) |
		(1ull << IB_USER_VERBS_CMD_QUERY_PORT) |
@@ -466,7 +461,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,

	switch (event) {
	case NETDEV_UP:
		sdev->state = IB_PORT_ACTIVE;
		siw_port_event(sdev, 1, IB_EVENT_PORT_ACTIVE);
		break;

@@ -475,7 +469,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
		break;

	case NETDEV_DOWN:
		sdev->state = IB_PORT_DOWN;
		siw_port_event(sdev, 1, IB_EVENT_PORT_ERR);
		break;

@@ -496,12 +489,8 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
		siw_port_event(sdev, 1, IB_EVENT_LID_CHANGE);
		break;
	/*
	 * Todo: Below netdev events are currently not handled.
	 * All other events are not handled
	 */
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGE:
		break;

	default:
		break;
	}
@@ -532,11 +521,6 @@ static int siw_newlink(const char *basedev_name, struct net_device *netdev)
	if (sdev) {
		dev_dbg(&netdev->dev, "siw: new device\n");

		if (netif_running(netdev) && netif_carrier_ok(netdev))
			sdev->state = IB_PORT_ACTIVE;
		else
			sdev->state = IB_PORT_DOWN;

		rv = siw_device_register(sdev, basedev_name);
		if (rv)
			ib_dealloc_device(&sdev->base_dev);
+28 −13
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/xarray.h>
#include <net/addrconf.h>

#include <rdma/iw_cm.h>
#include <rdma/ib_verbs.h>
@@ -155,7 +156,8 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr,
	attr->vendor_id = SIW_VENDOR_ID;
	attr->vendor_part_id = sdev->vendor_part_id;

	memcpy(&attr->sys_image_guid, sdev->netdev->dev_addr, 6);
	addrconf_addr_eui48((u8 *)&attr->sys_image_guid,
			    sdev->raw_gid);

	return 0;
}
@@ -163,21 +165,29 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr,
int siw_query_port(struct ib_device *base_dev, u8 port,
		   struct ib_port_attr *attr)
{
	struct siw_device *sdev = to_siw_dev(base_dev);
	struct net_device *ndev;
	int rv;

	memset(attr, 0, sizeof(*attr));

	rv = ib_get_eth_speed(base_dev, port, &attr->active_speed,
			 &attr->active_width);
	if (rv)
		return rv;

	ndev = ib_device_get_netdev(base_dev, SIW_PORT);
	if (!ndev)
		return -ENODEV;

	attr->gid_tbl_len = 1;
	attr->max_msg_sz = -1;
	attr->max_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);
	attr->active_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);
	attr->phys_state = sdev->state == IB_PORT_ACTIVE ?
	attr->max_mtu = ib_mtu_int_to_enum(ndev->max_mtu);
	attr->active_mtu = ib_mtu_int_to_enum(READ_ONCE(ndev->mtu));
	attr->phys_state = (netif_running(ndev) && netif_carrier_ok(ndev)) ?
		IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED;
	attr->state = attr->phys_state == IB_PORT_PHYS_STATE_LINK_UP ?
		IB_PORT_ACTIVE : IB_PORT_DOWN;
	attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP;
	attr->state = sdev->state;
	/*
	 * All zero
	 *
@@ -191,6 +201,7 @@ int siw_query_port(struct ib_device *base_dev, u8 port,
	 * attr->subnet_timeout = 0;
	 * attr->init_type_repy = 0;
	 */
	dev_put(ndev);
	return rv;
}

@@ -216,7 +227,7 @@ int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,

	/* subnet_prefix == interface_id == 0; */
	memset(gid, 0, sizeof(*gid));
	memcpy(&gid->raw[0], sdev->netdev->dev_addr, 6);
	memcpy(gid->raw, sdev->raw_gid, ETH_ALEN);

	return 0;
}
@@ -507,20 +518,23 @@ int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr,
		 int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
{
	struct siw_qp *qp;
	struct siw_device *sdev;
	struct net_device *ndev;

	if (base_qp && qp_attr && qp_init_attr) {
	if (base_qp && qp_attr && qp_init_attr)
		qp = to_siw_qp(base_qp);
		sdev = to_siw_dev(base_qp->device);
	} else {
	else
		return -EINVAL;
	}

	ndev = ib_device_get_netdev(base_qp->device, SIW_PORT);
	if (!ndev)
		return -ENODEV;

	qp_attr->cap.max_inline_data = SIW_MAX_INLINE;
	qp_attr->cap.max_send_wr = qp->attrs.sq_size;
	qp_attr->cap.max_send_sge = qp->attrs.sq_max_sges;
	qp_attr->cap.max_recv_wr = qp->attrs.rq_size;
	qp_attr->cap.max_recv_sge = qp->attrs.rq_max_sges;
	qp_attr->path_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);
	qp_attr->path_mtu = ib_mtu_int_to_enum(READ_ONCE(ndev->mtu));
	qp_attr->max_rd_atomic = qp->attrs.irq_size;
	qp_attr->max_dest_rd_atomic = qp->attrs.orq_size;

@@ -535,6 +549,7 @@ int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr,

	qp_init_attr->cap = qp_attr->cap;

	dev_put(ndev);
	return 0;
}