ASoC: sdw_utils: fix device reference leak in is_sdca_endpoint_present()

commit 1a58d865f4 upstream.

The bus_find_device_by_name() function returns a device pointer with an
incremented reference count, but the original code was missing put_device()
calls in some return paths, leading to reference count leaks.

Fix this by ensuring put_device() is called before function exit after
  bus_find_device_by_name() succeeds

This follows the same pattern used elsewhere in the kernel where
bus_find_device_by_name() is properly paired with put_device().

Found via static analysis and code review.

Fixes: 4f8ef33dd4 ("ASoC: soc_sdw_utils: skip the endpoint that doesn't present")
Cc: stable@vger.kernel.org
Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
Link: https://patch.msgid.link/20251029071804.8425-1-linmq006@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Miaoqian Lin
2025-10-29 15:17:58 +08:00
committed by Greg Kroah-Hartman
parent d2c04f20cc
commit 6ec1ecedad

View File

@@ -1239,7 +1239,7 @@ static int is_sdca_endpoint_present(struct device *dev,
struct sdw_slave *slave;
struct device *sdw_dev;
const char *sdw_codec_name;
int i;
int ret, i;
dlc = kzalloc(sizeof(*dlc), GFP_KERNEL);
if (!dlc)
@@ -1269,13 +1269,16 @@ static int is_sdca_endpoint_present(struct device *dev,
}
slave = dev_to_sdw_dev(sdw_dev);
if (!slave)
return -EINVAL;
if (!slave) {
ret = -EINVAL;
goto put_device;
}
/* Make sure BIOS provides SDCA properties */
if (!slave->sdca_data.interface_revision) {
dev_warn(&slave->dev, "SDCA properties not found in the BIOS\n");
return 1;
ret = 1;
goto put_device;
}
for (i = 0; i < slave->sdca_data.num_functions; i++) {
@@ -1284,7 +1287,8 @@ static int is_sdca_endpoint_present(struct device *dev,
if (dai_type == dai_info->dai_type) {
dev_dbg(&slave->dev, "DAI type %d sdca function %s found\n",
dai_type, slave->sdca_data.function[i].name);
return 1;
ret = 1;
goto put_device;
}
}
@@ -1292,7 +1296,11 @@ static int is_sdca_endpoint_present(struct device *dev,
"SDCA device function for DAI type %d not supported, skip endpoint\n",
dai_info->dai_type);
return 0;
ret = 0;
put_device:
put_device(sdw_dev);
return ret;
}
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,