Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spi: Use after free fixes

Johan Hovold <johan@kernel.org> says:

The SPI subsystem frees the controller and any subsystem allocated
driver data as part of deregistration (unless the allocation is device
managed).

This series fixes the IMX driver that got this wrong and then converts
it to use device managed allocation.

Included are also a (preparatory) deregistration fix for the rockchip
driver and related cleanups for the tegre20-slink and rockchip drivers
that both take a controller reference during unbind.

+40 -67
+14 -27
drivers/spi/spi-imx.c
··· 2231 2231 target_mode = devtype_data->has_targetmode && 2232 2232 of_property_read_bool(np, "spi-slave"); 2233 2233 if (target_mode) 2234 - controller = spi_alloc_target(&pdev->dev, 2235 - sizeof(struct spi_imx_data)); 2234 + controller = devm_spi_alloc_target(&pdev->dev, sizeof(*spi_imx)); 2236 2235 else 2237 - controller = spi_alloc_host(&pdev->dev, 2238 - sizeof(struct spi_imx_data)); 2236 + controller = devm_spi_alloc_host(&pdev->dev, sizeof(*spi_imx)); 2239 2237 if (!controller) 2240 2238 return -ENOMEM; 2241 2239 ··· 2302 2304 init_completion(&spi_imx->xfer_done); 2303 2305 2304 2306 spi_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 2305 - if (IS_ERR(spi_imx->base)) { 2306 - ret = PTR_ERR(spi_imx->base); 2307 - goto out_controller_put; 2308 - } 2307 + if (IS_ERR(spi_imx->base)) 2308 + return PTR_ERR(spi_imx->base); 2309 + 2309 2310 spi_imx->base_phys = res->start; 2310 2311 2311 2312 irq = platform_get_irq(pdev, 0); 2312 - if (irq < 0) { 2313 - ret = irq; 2314 - goto out_controller_put; 2315 - } 2313 + if (irq < 0) 2314 + return irq; 2316 2315 2317 2316 ret = devm_request_irq(&pdev->dev, irq, spi_imx_isr, 0, 2318 2317 dev_name(&pdev->dev), spi_imx); 2319 - if (ret) { 2320 - dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret); 2321 - goto out_controller_put; 2322 - } 2318 + if (ret) 2319 + return dev_err_probe(&pdev->dev, ret, "can't get irq%d\n", irq); 2323 2320 2324 2321 spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 2325 - if (IS_ERR(spi_imx->clk_ipg)) { 2326 - ret = PTR_ERR(spi_imx->clk_ipg); 2327 - goto out_controller_put; 2328 - } 2322 + if (IS_ERR(spi_imx->clk_ipg)) 2323 + return PTR_ERR(spi_imx->clk_ipg); 2329 2324 2330 2325 spi_imx->clk_per = devm_clk_get(&pdev->dev, "per"); 2331 - if (IS_ERR(spi_imx->clk_per)) { 2332 - ret = PTR_ERR(spi_imx->clk_per); 2333 - goto out_controller_put; 2334 - } 2326 + if (IS_ERR(spi_imx->clk_per)) 2327 + return PTR_ERR(spi_imx->clk_per); 2335 2328 2336 2329 ret = clk_prepare_enable(spi_imx->clk_per); 2337 2330 if (ret) 2338 - goto out_controller_put; 2331 + return ret; 2339 2332 2340 2333 ret = clk_prepare_enable(spi_imx->clk_ipg); 2341 2334 if (ret) ··· 2378 2389 clk_disable_unprepare(spi_imx->clk_ipg); 2379 2390 out_put_per: 2380 2391 clk_disable_unprepare(spi_imx->clk_per); 2381 - out_controller_put: 2382 - spi_controller_put(controller); 2383 2392 2384 2393 return ret; 2385 2394 }
+16 -24
drivers/spi/spi-rockchip.c
··· 767 767 target_mode = of_property_read_bool(np, "spi-slave"); 768 768 769 769 if (target_mode) 770 - ctlr = spi_alloc_target(&pdev->dev, sizeof(struct rockchip_spi)); 770 + ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*rs)); 771 771 else 772 - ctlr = spi_alloc_host(&pdev->dev, sizeof(struct rockchip_spi)); 772 + ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*rs)); 773 773 774 774 if (!ctlr) 775 775 return -ENOMEM; ··· 780 780 781 781 /* Get basic io resource and map it */ 782 782 rs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); 783 - if (IS_ERR(rs->regs)) { 784 - ret = PTR_ERR(rs->regs); 785 - goto err_put_ctlr; 786 - } 783 + if (IS_ERR(rs->regs)) 784 + return PTR_ERR(rs->regs); 787 785 788 786 rs->apb_pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); 789 787 if (IS_ERR(rs->apb_pclk)) { 790 - ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk), 791 - "Failed to get apb_pclk\n"); 792 - goto err_put_ctlr; 788 + return dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk), 789 + "Failed to get apb_pclk\n"); 793 790 } 794 791 795 792 rs->spiclk = devm_clk_get_enabled(&pdev->dev, "spiclk"); 796 793 if (IS_ERR(rs->spiclk)) { 797 - ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk), 798 - "Failed to get spi_pclk\n"); 799 - goto err_put_ctlr; 794 + return dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk), 795 + "Failed to get spi_pclk\n"); 800 796 } 801 797 802 798 spi_enable_chip(rs, false); 803 799 804 800 ret = platform_get_irq(pdev, 0); 805 801 if (ret < 0) 806 - goto err_put_ctlr; 802 + return ret; 807 803 808 804 ret = devm_request_irq(&pdev->dev, ret, rockchip_spi_isr, 0, 809 805 dev_name(&pdev->dev), ctlr); 810 806 if (ret) 811 - goto err_put_ctlr; 807 + return ret; 812 808 813 809 rs->dev = &pdev->dev; 814 810 rs->freq = clk_get_rate(rs->spiclk); ··· 826 830 } 827 831 828 832 rs->fifo_len = get_fifo_len(rs); 829 - if (!rs->fifo_len) { 830 - ret = dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n"); 831 - goto err_put_ctlr; 832 - } 833 + if (!rs->fifo_len) 834 + return dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n"); 833 835 834 836 pm_runtime_set_autosuspend_delay(&pdev->dev, ROCKCHIP_AUTOSUSPEND_TIMEOUT); 835 837 pm_runtime_use_autosuspend(&pdev->dev); ··· 902 908 break; 903 909 } 904 910 905 - ret = devm_spi_register_controller(&pdev->dev, ctlr); 911 + ret = spi_register_controller(ctlr); 906 912 if (ret < 0) { 907 913 dev_err(&pdev->dev, "Failed to register controller\n"); 908 914 goto err_free_dma_rx; ··· 918 924 dma_release_channel(ctlr->dma_tx); 919 925 err_disable_pm_runtime: 920 926 pm_runtime_disable(&pdev->dev); 921 - err_put_ctlr: 922 - spi_controller_put(ctlr); 923 927 924 928 return ret; 925 929 } 926 930 927 931 static void rockchip_spi_remove(struct platform_device *pdev) 928 932 { 929 - struct spi_controller *ctlr = spi_controller_get(platform_get_drvdata(pdev)); 933 + struct spi_controller *ctlr = platform_get_drvdata(pdev); 930 934 931 935 pm_runtime_get_sync(&pdev->dev); 936 + 937 + spi_unregister_controller(ctlr); 932 938 933 939 pm_runtime_put_noidle(&pdev->dev); 934 940 pm_runtime_disable(&pdev->dev); ··· 938 944 dma_release_channel(ctlr->dma_tx); 939 945 if (ctlr->dma_rx) 940 946 dma_release_channel(ctlr->dma_rx); 941 - 942 - spi_controller_put(ctlr); 943 947 } 944 948 945 949 #ifdef CONFIG_PM_SLEEP
+10 -16
drivers/spi/spi-tegra20-slink.c
··· 1007 1007 1008 1008 cdata = of_device_get_match_data(&pdev->dev); 1009 1009 1010 - host = spi_alloc_host(&pdev->dev, sizeof(*tspi)); 1010 + host = devm_spi_alloc_host(&pdev->dev, sizeof(*tspi)); 1011 1011 if (!host) { 1012 1012 dev_err(&pdev->dev, "host allocation failed\n"); 1013 1013 return -ENOMEM; ··· 1034 1034 host->max_speed_hz = 25000000; /* 25MHz */ 1035 1035 1036 1036 tspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); 1037 - if (IS_ERR(tspi->base)) { 1038 - ret = PTR_ERR(tspi->base); 1039 - goto exit_free_host; 1040 - } 1037 + if (IS_ERR(tspi->base)) 1038 + return PTR_ERR(tspi->base); 1039 + 1041 1040 tspi->phys = r->start; 1042 1041 1043 1042 /* disabled clock may cause interrupt storm upon request */ 1044 1043 tspi->clk = devm_clk_get(&pdev->dev, NULL); 1045 1044 if (IS_ERR(tspi->clk)) { 1046 1045 ret = PTR_ERR(tspi->clk); 1047 - dev_err(&pdev->dev, "Can not get clock %d\n", ret); 1048 - goto exit_free_host; 1046 + return dev_err_probe(&pdev->dev, ret, "Can not get clock\n"); 1049 1047 } 1050 1048 1051 1049 tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); 1052 1050 if (IS_ERR(tspi->rst)) { 1053 - dev_err(&pdev->dev, "can not get reset\n"); 1054 1051 ret = PTR_ERR(tspi->rst); 1055 - goto exit_free_host; 1052 + return dev_err_probe(&pdev->dev, ret, "can not get reset\n"); 1056 1053 } 1057 1054 1058 1055 ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); 1059 1056 if (ret) 1060 - goto exit_free_host; 1057 + return ret; 1061 1058 1062 1059 tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; 1063 1060 tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; 1064 1061 1065 1062 ret = tegra_slink_init_dma_param(tspi, true); 1066 1063 if (ret < 0) 1067 - goto exit_free_host; 1064 + return ret; 1068 1065 ret = tegra_slink_init_dma_param(tspi, false); 1069 1066 if (ret < 0) 1070 1067 goto exit_rx_dma_free; ··· 1122 1125 tegra_slink_deinit_dma_param(tspi, false); 1123 1126 exit_rx_dma_free: 1124 1127 tegra_slink_deinit_dma_param(tspi, true); 1125 - exit_free_host: 1126 - spi_controller_put(host); 1128 + 1127 1129 return ret; 1128 1130 } 1129 1131 1130 1132 static void tegra_slink_remove(struct platform_device *pdev) 1131 1133 { 1132 - struct spi_controller *host = spi_controller_get(platform_get_drvdata(pdev)); 1134 + struct spi_controller *host = platform_get_drvdata(pdev); 1133 1135 struct tegra_slink_data *tspi = spi_controller_get_devdata(host); 1134 1136 1135 1137 spi_unregister_controller(host); ··· 1142 1146 1143 1147 if (tspi->rx_dma_chan) 1144 1148 tegra_slink_deinit_dma_param(tspi, true); 1145 - 1146 - spi_controller_put(host); 1147 1149 } 1148 1150 1149 1151 #ifdef CONFIG_PM_SLEEP