We are facing crash due to null pointer dereference of stream in slim_stream_disable(). there is a possible scenario where client driver is calling slimbus stream APIs in incorrect sequence and it might lead to null pointer access of the stream in slimbus enable/disable/prepare/unprepare/free functions. Fix this issue by adding null pointer check of the stream before accessing in all stream API’s exposed to client. Signed-off-by: Viken Dadhaniya <quic_vdadhani@xxxxxxxxxxx> --- drivers/slimbus/stream.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c index 1d6b38657917..c5a436fd0952 100644 --- a/drivers/slimbus/stream.c +++ b/drivers/slimbus/stream.c @@ -202,10 +202,16 @@ static int slim_get_prate_code(int rate) int slim_stream_prepare(struct slim_stream_runtime *rt, struct slim_stream_config *cfg) { - struct slim_controller *ctrl = rt->dev->ctrl; + struct slim_controller *ctrl; struct slim_port *port; int num_ports, i, port_id, prrate; + if (!rt || !cfg) { + pr_err("%s: Stream or cfg is NULL, Check from client side\n", __func__); + return -EINVAL; + } + + ctrl = rt->dev->ctrl; if (rt->ports) { dev_err(&rt->dev->dev, "Stream already Prepared\n"); return -EINVAL; @@ -358,9 +364,15 @@ int slim_stream_enable(struct slim_stream_runtime *stream) { DEFINE_SLIM_BCAST_TXN(txn, SLIM_MSG_MC_BEGIN_RECONFIGURATION, 3, SLIM_LA_MANAGER, NULL); - struct slim_controller *ctrl = stream->dev->ctrl; + struct slim_controller *ctrl; int ret, i; + if (!stream) { + pr_err("%s: Stream is NULL, Check from client side\n", __func__); + return -EINVAL; + } + + ctrl = stream->dev->ctrl; if (ctrl->enable_stream) { ret = ctrl->enable_stream(stream); if (ret) @@ -411,12 +423,18 @@ int slim_stream_disable(struct slim_stream_runtime *stream) { DEFINE_SLIM_BCAST_TXN(txn, SLIM_MSG_MC_BEGIN_RECONFIGURATION, 3, SLIM_LA_MANAGER, NULL); - struct slim_controller *ctrl = stream->dev->ctrl; + struct slim_controller *ctrl; int ret, i; + if (!stream) { + pr_err("%s: Stream is NULL, Check from client side\n", __func__); + return -EINVAL; + } + if (!stream->ports || !stream->num_ports) return -EINVAL; + ctrl = stream->dev->ctrl; if (ctrl->disable_stream) ctrl->disable_stream(stream); @@ -448,6 +466,11 @@ int slim_stream_unprepare(struct slim_stream_runtime *stream) { int i; + if (!stream) { + pr_err("%s: Stream is NULL, Check from client side\n", __func__); + return -EINVAL; + } + if (!stream->ports || !stream->num_ports) return -EINVAL; @@ -476,8 +499,14 @@ EXPORT_SYMBOL_GPL(slim_stream_unprepare); */ int slim_stream_free(struct slim_stream_runtime *stream) { - struct slim_device *sdev = stream->dev; + struct slim_device *sdev; + + if (!stream) { + pr_err("%s: Stream is NULL, Check from client side\n", __func__); + return -EINVAL; + } + sdev = stream->dev; spin_lock(&sdev->stream_list_lock); list_del(&stream->node); spin_unlock(&sdev->stream_list_lock); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation