| From 0b364cf53b20204e92bac7c6ebd1ee7d3ec62931 Mon Sep 17 00:00:00 2001 |
| From: Philipp Stanner <pstanner@redhat.com> |
| Date: Mon, 28 Oct 2024 08:43:59 +0100 |
| Subject: vdpa: solidrun: Fix UB bug with devres |
| |
| From: Philipp Stanner <pstanner@redhat.com> |
| |
| commit 0b364cf53b20204e92bac7c6ebd1ee7d3ec62931 upstream. |
| |
| In psnet_open_pf_bar() and snet_open_vf_bar() a string later passed to |
| pcim_iomap_regions() is placed on the stack. Neither |
| pcim_iomap_regions() nor the functions it calls copy that string. |
| |
| Should the string later ever be used, this, consequently, causes |
| undefined behavior since the stack frame will by then have disappeared. |
| |
| Fix the bug by allocating the strings on the heap through |
| devm_kasprintf(). |
| |
| Cc: stable@vger.kernel.org # v6.3 |
| Fixes: 51a8f9d7f587 ("virtio: vdpa: new SolidNET DPU driver.") |
| Reported-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> |
| Closes: https://lore.kernel.org/all/74e9109a-ac59-49e2-9b1d-d825c9c9f891@wanadoo.fr/ |
| Suggested-by: Andy Shevchenko <andy@kernel.org> |
| Signed-off-by: Philipp Stanner <pstanner@redhat.com> |
| Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> |
| Message-Id: <20241028074357.9104-3-pstanner@redhat.com> |
| Signed-off-by: Michael S. Tsirkin <mst@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/vdpa/solidrun/snet_main.c | 14 ++++++++++---- |
| 1 file changed, 10 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/vdpa/solidrun/snet_main.c |
| +++ b/drivers/vdpa/solidrun/snet_main.c |
| @@ -555,7 +555,7 @@ static const struct vdpa_config_ops snet |
| |
| static int psnet_open_pf_bar(struct pci_dev *pdev, struct psnet *psnet) |
| { |
| - char name[50]; |
| + char *name; |
| int ret, i, mask = 0; |
| /* We don't know which BAR will be used to communicate.. |
| * We will map every bar with len > 0. |
| @@ -573,7 +573,10 @@ static int psnet_open_pf_bar(struct pci_ |
| return -ENODEV; |
| } |
| |
| - snprintf(name, sizeof(name), "psnet[%s]-bars", pci_name(pdev)); |
| + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "psnet[%s]-bars", pci_name(pdev)); |
| + if (!name) |
| + return -ENOMEM; |
| + |
| ret = pcim_iomap_regions(pdev, mask, name); |
| if (ret) { |
| SNET_ERR(pdev, "Failed to request and map PCI BARs\n"); |
| @@ -590,10 +593,13 @@ static int psnet_open_pf_bar(struct pci_ |
| |
| static int snet_open_vf_bar(struct pci_dev *pdev, struct snet *snet) |
| { |
| - char name[50]; |
| + char *name; |
| int ret; |
| |
| - snprintf(name, sizeof(name), "snet[%s]-bar", pci_name(pdev)); |
| + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "snet[%s]-bars", pci_name(pdev)); |
| + if (!name) |
| + return -ENOMEM; |
| + |
| /* Request and map BAR */ |
| ret = pcim_iomap_regions(pdev, BIT(snet->psnet->cfg.vf_bar), name); |
| if (ret) { |