aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-12-20 05:31:11 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-02-19 15:16:52 -0500
commit9d092603cc306ee6edfe917bf9ab8beb5f32d7bc (patch)
treeb3a2c673762e0c5c9cff298cf34376f887641f66 /drivers/block/xen-blkback
parent836dc9e3fbbab0c30aa6e664417225f5c1fb1c39 (diff)
xen-blkback: do not leak mode property
"be->mode" is obtained from xenbus_read(), which does a kmalloc() for the message body. The short string is never released, so do it along with freeing "be" itself, and make sure the string isn't kept when backend_changed() doesn't complete successfully (which made it desirable to slightly re-structure that function, so that the error cleanup can be done in one place). Reported-by: Olaf Hering <olaf@aepfle.de> CC: stable@vger.kernel.org Signed-off-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback')
-rw-r--r--drivers/block/xen-blkback/xenbus.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 63980722db41..5e237f630c47 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -367,6 +367,7 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
367 be->blkif = NULL; 367 be->blkif = NULL;
368 } 368 }
369 369
370 kfree(be->mode);
370 kfree(be); 371 kfree(be);
371 dev_set_drvdata(&dev->dev, NULL); 372 dev_set_drvdata(&dev->dev, NULL);
372 return 0; 373 return 0;
@@ -502,6 +503,7 @@ static void backend_changed(struct xenbus_watch *watch,
502 = container_of(watch, struct backend_info, backend_watch); 503 = container_of(watch, struct backend_info, backend_watch);
503 struct xenbus_device *dev = be->dev; 504 struct xenbus_device *dev = be->dev;
504 int cdrom = 0; 505 int cdrom = 0;
506 unsigned long handle;
505 char *device_type; 507 char *device_type;
506 508
507 DPRINTK(""); 509 DPRINTK("");
@@ -521,10 +523,10 @@ static void backend_changed(struct xenbus_watch *watch,
521 return; 523 return;
522 } 524 }
523 525
524 if ((be->major || be->minor) && 526 if (be->major | be->minor) {
525 ((be->major != major) || (be->minor != minor))) { 527 if (be->major != major || be->minor != minor)
526 pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", 528 pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
527 be->major, be->minor, major, minor); 529 be->major, be->minor, major, minor);
528 return; 530 return;
529 } 531 }
530 532
@@ -542,36 +544,33 @@ static void backend_changed(struct xenbus_watch *watch,
542 kfree(device_type); 544 kfree(device_type);
543 } 545 }
544 546
545 if (be->major == 0 && be->minor == 0) { 547 /* Front end dir is a number, which is used as the handle. */
546 /* Front end dir is a number, which is used as the handle. */ 548 err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle);
547 549 if (err)
548 char *p = strrchr(dev->otherend, '/') + 1; 550 return;
549 long handle;
550 err = strict_strtoul(p, 0, &handle);
551 if (err)
552 return;
553 551
554 be->major = major; 552 be->major = major;
555 be->minor = minor; 553 be->minor = minor;
556 554
557 err = xen_vbd_create(be->blkif, handle, major, minor, 555 err = xen_vbd_create(be->blkif, handle, major, minor,
558 (NULL == strchr(be->mode, 'w')), cdrom); 556 !strchr(be->mode, 'w'), cdrom);
559 if (err) {
560 be->major = 0;
561 be->minor = 0;
562 xenbus_dev_fatal(dev, err, "creating vbd structure");
563 return;
564 }
565 557
558 if (err)
559 xenbus_dev_fatal(dev, err, "creating vbd structure");
560 else {
566 err = xenvbd_sysfs_addif(dev); 561 err = xenvbd_sysfs_addif(dev);
567 if (err) { 562 if (err) {
568 xen_vbd_free(&be->blkif->vbd); 563 xen_vbd_free(&be->blkif->vbd);
569 be->major = 0;
570 be->minor = 0;
571 xenbus_dev_fatal(dev, err, "creating sysfs entries"); 564 xenbus_dev_fatal(dev, err, "creating sysfs entries");
572 return;
573 } 565 }
566 }
574 567
568 if (err) {
569 kfree(be->mode);
570 be->mode = NULL;
571 be->major = 0;
572 be->minor = 0;
573 } else {
575 /* We're potentially connected now */ 574 /* We're potentially connected now */
576 xen_update_blkif_status(be->blkif); 575 xen_update_blkif_status(be->blkif);
577 } 576 }