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

!9697 v3 Fix CVE-2024-38567

Merge Pull Request from: @ci-robot 
 
PR sync from: Li Huafei <lihuafei1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/TDZQJQBOEWTUZKRM5KS5BC4DHMWQHSLQ/ 
Alan Stern (1):
  USB: core: Add routines for endpoint checks in old drivers

Nikita Zhandarovich (1):
  wifi: carl9170: add a proper sanity check for endpoints


-- 
2.25.1
 
https://gitee.com/src-openeuler/kernel/issues/IA6S5Z 
 
Link:https://gitee.com/openeuler/kernel/pulls/9697

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Reviewed-by: default avatarLiu YongQiang <liuyongqiang13@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parents 4b6f9d4a 1e973323
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -1069,6 +1069,38 @@ static int carl9170_usb_probe(struct usb_interface *intf,
			ar->usb_ep_cmd_is_bulk = true;
	}

	/* Verify that all expected endpoints are present */
	if (ar->usb_ep_cmd_is_bulk) {
		u8 bulk_ep_addr[] = {
			AR9170_USB_EP_RX | USB_DIR_IN,
			AR9170_USB_EP_TX | USB_DIR_OUT,
			AR9170_USB_EP_CMD | USB_DIR_OUT,
			0};
		u8 int_ep_addr[] = {
			AR9170_USB_EP_IRQ | USB_DIR_IN,
			0};
		if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
		    !usb_check_int_endpoints(intf, int_ep_addr))
			err = -ENODEV;
	} else {
		u8 bulk_ep_addr[] = {
			AR9170_USB_EP_RX | USB_DIR_IN,
			AR9170_USB_EP_TX | USB_DIR_OUT,
			0};
		u8 int_ep_addr[] = {
			AR9170_USB_EP_IRQ | USB_DIR_IN,
			AR9170_USB_EP_CMD | USB_DIR_OUT,
			0};
		if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
		    !usb_check_int_endpoints(intf, int_ep_addr))
			err = -ENODEV;
	}

	if (err) {
		carl9170_free(ar);
		return err;
	}

	usb_set_intfdata(intf, ar);
	SET_IEEE80211_DEV(ar->hw, &intf->dev);

+76 −0
Original line number Diff line number Diff line
@@ -209,6 +209,82 @@ int usb_find_common_endpoints_reverse(struct usb_host_interface *alt,
}
EXPORT_SYMBOL_GPL(usb_find_common_endpoints_reverse);

/**
 * usb_find_endpoint() - Given an endpoint address, search for the endpoint's
 * usb_host_endpoint structure in an interface's current altsetting.
 * @intf: the interface whose current altsetting should be searched
 * @ep_addr: the endpoint address (number and direction) to find
 *
 * Search the altsetting's list of endpoints for one with the specified address.
 *
 * Return: Pointer to the usb_host_endpoint if found, %NULL otherwise.
 */
static const struct usb_host_endpoint *usb_find_endpoint(
		const struct usb_interface *intf, unsigned int ep_addr)
{
	int n;
	const struct usb_host_endpoint *ep;

	n = intf->cur_altsetting->desc.bNumEndpoints;
	ep = intf->cur_altsetting->endpoint;
	for (; n > 0; (--n, ++ep)) {
		if (ep->desc.bEndpointAddress == ep_addr)
			return ep;
	}
	return NULL;
}

/**
 * usb_check_bulk_endpoints - Check whether an interface's current altsetting
 * contains a set of bulk endpoints with the given addresses.
 * @intf: the interface whose current altsetting should be searched
 * @ep_addrs: 0-terminated array of the endpoint addresses (number and
 * direction) to look for
 *
 * Search for endpoints with the specified addresses and check their types.
 *
 * Return: %true if all the endpoints are found and are bulk, %false otherwise.
 */
bool usb_check_bulk_endpoints(
		const struct usb_interface *intf, const u8 *ep_addrs)
{
	const struct usb_host_endpoint *ep;

	for (; *ep_addrs; ++ep_addrs) {
		ep = usb_find_endpoint(intf, *ep_addrs);
		if (!ep || !usb_endpoint_xfer_bulk(&ep->desc))
			return false;
	}
	return true;
}
EXPORT_SYMBOL_GPL(usb_check_bulk_endpoints);

/**
 * usb_check_int_endpoints - Check whether an interface's current altsetting
 * contains a set of interrupt endpoints with the given addresses.
 * @intf: the interface whose current altsetting should be searched
 * @ep_addrs: 0-terminated array of the endpoint addresses (number and
 * direction) to look for
 *
 * Search for endpoints with the specified addresses and check their types.
 *
 * Return: %true if all the endpoints are found and are interrupt,
 * %false otherwise.
 */
bool usb_check_int_endpoints(
		const struct usb_interface *intf, const u8 *ep_addrs)
{
	const struct usb_host_endpoint *ep;

	for (; *ep_addrs; ++ep_addrs) {
		ep = usb_find_endpoint(intf, *ep_addrs);
		if (!ep || !usb_endpoint_xfer_int(&ep->desc))
			return false;
	}
	return true;
}
EXPORT_SYMBOL_GPL(usb_check_int_endpoints);

/**
 * usb_find_alt_setting() - Given a configuration, find the alternate setting
 * for the given interface.
+5 −0
Original line number Diff line number Diff line
@@ -279,6 +279,11 @@ void usb_put_intf(struct usb_interface *intf);
#define USB_MAXINTERFACES	32
#define USB_MAXIADS		(USB_MAXINTERFACES/2)

bool usb_check_bulk_endpoints(
		const struct usb_interface *intf, const u8 *ep_addrs);
bool usb_check_int_endpoints(
		const struct usb_interface *intf, const u8 *ep_addrs);

/*
 * USB Resume Timer: Every Host controller driver should drive the resume
 * signalling on the bus for the amount of time defined by this macro.