Whamcloud - gitweb
LU-4134 obdclass: fix double free in failure path 67/29967/8
authorYang Sheng <yang.sheng@intel.com>
Mon, 27 Nov 2017 21:14:49 +0000 (16:14 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Dec 2017 03:45:53 +0000 (03:45 +0000)
We should just decref for obd if register is failed.
Since class_export_put will invoke class_free_dev,
then we may face a double free.

Signed-off-by: Yang Sheng <yang.sheng@intel.com>
Change-Id: Ia8d1e487c69c4de1c7c247158cc8615aa6b6093a
Reviewed-on: https://review.whamcloud.com/29967
Reviewed-by: Alexey Lyashkov <c17817@cray.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/obdclass/obd_config.c

index 056ef94..1b735bf 100644 (file)
@@ -396,15 +396,12 @@ int class_attach(struct lustre_cfg *lcfg)
        }
 
        obd = class_newdev(typename, name, uuid);
-        if (IS_ERR(obd)) {
-                /* Already exists or out of obds */
-                rc = PTR_ERR(obd);
+       if (IS_ERR(obd)) { /* Already exists or out of obds */
+               rc = PTR_ERR(obd);
                 CERROR("Cannot create device %s of type %s : %d\n",
                        name, typename, rc);
                RETURN(rc);
         }
-        LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
-                 name, typename);
         LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
                  "obd %p obd_magic %08X != %08X\n",
                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);
@@ -413,9 +410,9 @@ int class_attach(struct lustre_cfg *lcfg)
 
        exp = class_new_export_self(obd, &obd->obd_uuid);
        if (IS_ERR(exp)) {
-               /* force free */
-               GOTO(out, rc = PTR_ERR(exp));
-               RETURN(PTR_ERR(exp));
+               rc = PTR_ERR(exp);
+               class_free_dev(obd);
+               RETURN(rc);
        }
 
        obd->obd_self_export = exp;
@@ -423,18 +420,16 @@ int class_attach(struct lustre_cfg *lcfg)
        class_export_put(exp);
 
        rc = class_register_device(obd);
-       if (rc != 0)
-               GOTO(out, rc);
+       if (rc != 0) {
+               class_decref(obd, "newdev", obd);
+               RETURN(rc);
+       }
 
        obd->obd_attached = 1;
        CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
               obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
-       RETURN(0);
-out:
-       class_decref(obd, "newdev", obd);
-       class_free_dev(obd);
 
-       RETURN(rc);
+       RETURN(0);
 }
 EXPORT_SYMBOL(class_attach);
 
@@ -733,10 +728,6 @@ void class_decref(struct obd_device *obd, const char *scope, const void *source)
 
                if (exp) {
                        exp->exp_flags |= exp_flags_from_obd(obd);
-                       /*
-                        * note that we'll recurse into class_decref again
-                        * but it's not a problem because we was last user
-                        */
                        class_unlink_export(exp);
                 }
         }