Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d84b9e5 authored by Shawn Lin's avatar Shawn Lin Committed by Ulf Hansson
Browse files

mmc: dw_mmc: Fix out-of-bounds access for slot's caps



Add num_caps field for dw_mci_drv_data to validate the controller
id from DT alias and non-DT ways.

Reported-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarShawn Lin <shawn.lin@rock-chips.com>
Fixes: 800d78bf ("mmc: dw_mmc: add support for implementation specific callbacks")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent a4faa492
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ static unsigned long exynos_dwmmc_caps[4] = {

static const struct dw_mci_drv_data exynos_drv_data = {
	.caps			= exynos_dwmmc_caps,
	.num_caps		= ARRAY_SIZE(exynos_dwmmc_caps),
	.init			= dw_mci_exynos_priv_init,
	.set_ios		= dw_mci_exynos_set_ios,
	.parse_dt		= dw_mci_exynos_parse_dt,
+1 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ static int dw_mci_hi6220_execute_tuning(struct dw_mci_slot *slot, u32 opcode)

static const struct dw_mci_drv_data hi6220_data = {
	.caps			= dw_mci_hi6220_caps,
	.num_caps		= ARRAY_SIZE(dw_mci_hi6220_caps),
	.switch_voltage		= dw_mci_hi6220_switch_voltage,
	.set_ios		= dw_mci_hi6220_set_ios,
	.parse_dt		= dw_mci_hi6220_parse_dt,
+1 −0
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ static const struct dw_mci_drv_data rk2928_drv_data = {

static const struct dw_mci_drv_data rk3288_drv_data = {
	.caps			= dw_mci_rk3288_dwmmc_caps,
	.num_caps		= ARRAY_SIZE(dw_mci_rk3288_dwmmc_caps),
	.set_ios		= dw_mci_rk3288_set_ios,
	.execute_tuning		= dw_mci_rk3288_execute_tuning,
	.parse_dt		= dw_mci_rk3288_parse_dt,
+1 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ static unsigned long zx_dwmmc_caps[3] = {

static const struct dw_mci_drv_data zx_drv_data = {
	.caps			= zx_dwmmc_caps,
	.num_caps		= ARRAY_SIZE(zx_dwmmc_caps),
	.execute_tuning		= dw_mci_zx_execute_tuning,
	.prepare_hs400_tuning	= dw_mci_zx_prepare_hs400_tuning,
	.parse_dt               = dw_mci_zx_parse_dt,
+8 −1
Original line number Diff line number Diff line
@@ -2804,8 +2804,15 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
	} else {
		ctrl_id = to_platform_device(host->dev)->id;
	}
	if (drv_data && drv_data->caps)

	if (drv_data && drv_data->caps) {
		if (ctrl_id >= drv_data->num_caps) {
			dev_err(host->dev, "invalid controller id %d\n",
				ctrl_id);
			return -EINVAL;
		}
		mmc->caps |= drv_data->caps[ctrl_id];
	}

	if (host->pdata->caps2)
		mmc->caps2 = host->pdata->caps2;
Loading