aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-24 06:11:02 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 11:48:30 -0500
commit44961a03adbf16d872f0b83ec848d0759516d33f (patch)
treeba0e93fd1a473d93370d56c77416c44de6e9b3f9 /drivers/pcmcia
parentc3bfc96ef7366aa996fb8286a36f3333a3b4ff25 (diff)
pcmcia: avoid prod_id memleak
Reported-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/ds.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 9968c0d3a5fb..93925f5908b8 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -237,8 +237,11 @@ static void pcmcia_release_function(struct kref *ref)
237static void pcmcia_release_dev(struct device *dev) 237static void pcmcia_release_dev(struct device *dev)
238{ 238{
239 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 239 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
240 int i;
240 dev_dbg(dev, "releasing device\n"); 241 dev_dbg(dev, "releasing device\n");
241 pcmcia_put_socket(p_dev->socket); 242 pcmcia_put_socket(p_dev->socket);
243 for (i = 0; i < 4; i++)
244 kfree(p_dev->prod_id[i]);
242 kfree(p_dev->devname); 245 kfree(p_dev->devname);
243 kref_put(&p_dev->function_config->ref, pcmcia_release_function); 246 kref_put(&p_dev->function_config->ref, pcmcia_release_function);
244 kfree(p_dev); 247 kfree(p_dev);
@@ -450,6 +453,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
450 for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) { 453 for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
451 char *tmp; 454 char *tmp;
452 unsigned int length; 455 unsigned int length;
456 char *new;
453 457
454 tmp = vers1->str + vers1->ofs[i]; 458 tmp = vers1->str + vers1->ofs[i];
455 459
@@ -457,13 +461,15 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
457 if ((length < 2) || (length > 255)) 461 if ((length < 2) || (length > 255))
458 continue; 462 continue;
459 463
460 p_dev->prod_id[i] = kmalloc(sizeof(char) * length, 464 new = kmalloc(sizeof(char) * length, GFP_KERNEL);
461 GFP_KERNEL); 465 if (!new)
462 if (!p_dev->prod_id[i])
463 continue; 466 continue;
464 467
465 p_dev->prod_id[i] = strncpy(p_dev->prod_id[i], 468 new = strncpy(new, tmp, length);
466 tmp, length); 469
470 tmp = p_dev->prod_id[i];
471 p_dev->prod_id[i] = new;
472 kfree(tmp);
467 } 473 }
468 mutex_unlock(&p_dev->socket->ops_mutex); 474 mutex_unlock(&p_dev->socket->ops_mutex);
469 } 475 }
@@ -485,6 +491,7 @@ static DEFINE_MUTEX(device_add_lock);
485struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) 491struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
486{ 492{
487 struct pcmcia_device *p_dev, *tmp_dev; 493 struct pcmcia_device *p_dev, *tmp_dev;
494 int i;
488 495
489 s = pcmcia_get_socket(s); 496 s = pcmcia_get_socket(s);
490 if (!s) 497 if (!s)
@@ -575,6 +582,8 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
575 s->device_count--; 582 s->device_count--;
576 mutex_unlock(&s->ops_mutex); 583 mutex_unlock(&s->ops_mutex);
577 584
585 for (i = 0; i < 4; i++)
586 kfree(p_dev->prod_id[i]);
578 kfree(p_dev->devname); 587 kfree(p_dev->devname);
579 kfree(p_dev); 588 kfree(p_dev);
580 err_put: 589 err_put: