aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJulia Lawall <julia@diku.dk>2011-08-08 02:28:50 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-13 21:00:32 -0400
commit951f2f960e5bbce20309de44626cf11d17847712 (patch)
tree23b4a76dbb70f036e9b756c70205e5c740f9ce12 /drivers
parent75bc8ef528f7c4ea7e80384c5593487b6b3b535e (diff)
drivers/net/can/sja1000/plx_pci.c: eliminate double free
In this code, the failure_cleanup label calls the function plx_pci_del_card, which frees everything in the card->net_dev array. dev is placed in this array immediately after allocation, so the two subsequent jumps to failure_cleanup should not also call free_sja1000dev, but the second one does. If plx_pci_check_sja1000 fails, then free_sja1000dev is also called on dev. Because dev is already in the card->net_dev array, this implies that when plx_pci_del_card is later called, it may get freed again. So that entry is reset to NULL after the free. Finally, if there is a problem with one channel, there will be a hole in the array. card->channels counts the number of channels that have succeeded, and does not keep track of the index of the largest element in the array that is valid. So the loop in plx_pci_del_card is changed to go up to PLX_PCI_MAX_CHAN, which is only 2. Signed-off-by: Julia Lawall <julia@diku.dk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/can/sja1000/plx_pci.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index 231385b8e08f..c7f3d4ea1167 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -408,7 +408,7 @@ static void plx_pci_del_card(struct pci_dev *pdev)
408 struct sja1000_priv *priv; 408 struct sja1000_priv *priv;
409 int i = 0; 409 int i = 0;
410 410
411 for (i = 0; i < card->channels; i++) { 411 for (i = 0; i < PLX_PCI_MAX_CHAN; i++) {
412 dev = card->net_dev[i]; 412 dev = card->net_dev[i];
413 if (!dev) 413 if (!dev)
414 continue; 414 continue;
@@ -536,7 +536,6 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
536 if (err) { 536 if (err) {
537 dev_err(&pdev->dev, "Registering device failed " 537 dev_err(&pdev->dev, "Registering device failed "
538 "(err=%d)\n", err); 538 "(err=%d)\n", err);
539 free_sja1000dev(dev);
540 goto failure_cleanup; 539 goto failure_cleanup;
541 } 540 }
542 541
@@ -549,6 +548,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev,
549 dev_err(&pdev->dev, "Channel #%d not detected\n", 548 dev_err(&pdev->dev, "Channel #%d not detected\n",
550 i + 1); 549 i + 1);
551 free_sja1000dev(dev); 550 free_sja1000dev(dev);
551 card->net_dev[i] = NULL;
552 } 552 }
553 } 553 }
554 554