Skip to content

Commit c3b56da

Browse files
committed
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: Arnd Bergmann <arnd@arndb.de>
2 parents e5c06ef + 5496270 commit c3b56da

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

Documentation/devicetree/bindings/firmware/arm,scmi.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ properties:
124124
atomic mode of operation, even if requested.
125125
default: 0
126126

127-
max-rx-timeout-ms:
127+
arm,max-rx-timeout-ms:
128128
description:
129129
An optional time value, expressed in milliseconds, representing the
130130
transport maximum timeout value for the receive channel. The value should

drivers/firmware/arm_scmi/bus.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ EXPORT_SYMBOL_GPL(scmi_driver_unregister);
325325

326326
static void scmi_device_release(struct device *dev)
327327
{
328-
kfree(to_scmi_dev(dev));
328+
struct scmi_device *scmi_dev = to_scmi_dev(dev);
329+
330+
kfree_const(scmi_dev->name);
331+
kfree(scmi_dev);
329332
}
330333

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

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

411413
return scmi_dev;
412414
put_dev:
413-
kfree_const(scmi_dev->name);
414415
put_device(&scmi_dev->dev);
415416
ida_free(&scmi_bus_id, id);
416417
return NULL;

drivers/firmware/arm_scmi/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
163163
* used to initialize this channel
164164
* @dev: Reference to device in the SCMI hierarchy corresponding to this
165165
* channel
166+
* @is_p2a: A flag to identify a channel as P2A (RX)
166167
* @rx_timeout_ms: The configured RX timeout in milliseconds.
167168
* @handle: Pointer to SCMI entity handle
168169
* @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);
174175
struct scmi_chan_info {
175176
int id;
176177
struct device *dev;
178+
bool is_p2a;
177179
unsigned int rx_timeout_ms;
178180
struct scmi_handle *handle;
179181
bool no_completion_irq;

drivers/firmware/arm_scmi/driver.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,11 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
10481048
static inline void scmi_clear_channel(struct scmi_info *info,
10491049
struct scmi_chan_info *cinfo)
10501050
{
1051+
if (!cinfo->is_p2a) {
1052+
dev_warn(cinfo->dev, "Invalid clear on A2P channel !\n");
1053+
return;
1054+
}
1055+
10511056
if (info->desc->ops->clear_channel)
10521057
info->desc->ops->clear_channel(cinfo);
10531058
}
@@ -2638,6 +2643,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
26382643
if (!cinfo)
26392644
return -ENOMEM;
26402645

2646+
cinfo->is_p2a = !tx;
26412647
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
26422648

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

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

3045-
ret = of_property_read_u32(dev->of_node, "max-rx-timeout-ms",
3051+
ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms",
30463052
&trans->desc->max_rx_timeout_ms);
30473053
if (ret && ret != -EINVAL)
3048-
dev_err(dev, "Malformed max-rx-timeout-ms DT property.\n");
3054+
dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n");
30493055

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

0 commit comments

Comments
 (0)