Unverified Commit c3b56da6 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'scmi-fixes-6.12-2' of...

Merge tag 'scmi-fixes-6.12-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into HEAD

Arm SCMI fixes for v6.12(part 2)

Couple of fixes to address slab-use-after-free in scmi_bus_notifier()
via scmi_dev->name and possible incorrect clear channel transport
operation on A2P channel if some sort of P2A only messages are initiated
on A2P channel(occurs when stress tested passing /dev/random to the
channel).

Apart from this, there are fixes to address missing "arm" prefix in the
recently added property max-rx-timeout-ms which was missed in the review
but was identified when further additions to the same binding were
getting reviewed.

* tag 'scmi-fixes-6.12-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  firmware: arm_scmi: Use vendor string in max-rx-timeout-ms
  dt-bindings: firmware: arm,scmi: Add missing vendor string
  firmware: arm_scmi: Reject clear channel request on A2P
  firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()

Link: https://lore.kernel.org/r/20241031172734.3109140-1-sudeep.holla@arm.com


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents e5c06efd 54962707
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ properties:
      atomic mode of operation, even if requested.
    default: 0

  max-rx-timeout-ms:
  arm,max-rx-timeout-ms:
    description:
      An optional time value, expressed in milliseconds, representing the
      transport maximum timeout value for the receive channel. The value should
+4 −3
Original line number Diff line number Diff line
@@ -325,7 +325,10 @@ EXPORT_SYMBOL_GPL(scmi_driver_unregister);

static void scmi_device_release(struct device *dev)
{
	kfree(to_scmi_dev(dev));
	struct scmi_device *scmi_dev = to_scmi_dev(dev);

	kfree_const(scmi_dev->name);
	kfree(scmi_dev);
}

static void __scmi_device_destroy(struct scmi_device *scmi_dev)
@@ -338,7 +341,6 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev)
	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
		atomic_set(&scmi_syspower_registered, 0);

	kfree_const(scmi_dev->name);
	ida_free(&scmi_bus_id, scmi_dev->id);
	device_unregister(&scmi_dev->dev);
}
@@ -410,7 +412,6 @@ __scmi_device_create(struct device_node *np, struct device *parent,

	return scmi_dev;
put_dev:
	kfree_const(scmi_dev->name);
	put_device(&scmi_dev->dev);
	ida_free(&scmi_bus_id, id);
	return NULL;
+2 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
 *      used to initialize this channel
 * @dev: Reference to device in the SCMI hierarchy corresponding to this
 *	 channel
 * @is_p2a: A flag to identify a channel as P2A (RX)
 * @rx_timeout_ms: The configured RX timeout in milliseconds.
 * @handle: Pointer to SCMI entity handle
 * @no_completion_irq: Flag to indicate that this channel has no completion
@@ -174,6 +175,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
struct scmi_chan_info {
	int id;
	struct device *dev;
	bool is_p2a;
	unsigned int rx_timeout_ms;
	struct scmi_handle *handle;
	bool no_completion_irq;
+8 −2
Original line number Diff line number Diff line
@@ -1048,6 +1048,11 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
static inline void scmi_clear_channel(struct scmi_info *info,
				      struct scmi_chan_info *cinfo)
{
	if (!cinfo->is_p2a) {
		dev_warn(cinfo->dev, "Invalid clear on A2P channel !\n");
		return;
	}

	if (info->desc->ops->clear_channel)
		info->desc->ops->clear_channel(cinfo);
}
@@ -2638,6 +2643,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
	if (!cinfo)
		return -ENOMEM;

	cinfo->is_p2a = !tx;
	cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;

	/* Create a unique name for this transport device */
@@ -3042,10 +3048,10 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)

	dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier));

	ret = of_property_read_u32(dev->of_node, "max-rx-timeout-ms",
	ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms",
				   &trans->desc->max_rx_timeout_ms);
	if (ret && ret != -EINVAL)
		dev_err(dev, "Malformed max-rx-timeout-ms DT property.\n");
		dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n");

	dev_info(dev, "SCMI max-rx-timeout: %dms\n",
		 trans->desc->max_rx_timeout_ms);