From 77d2e604b6bc3c319adefca069b5182c325a43b0 Mon Sep 17 00:00:00 2001 From: Yang Sheng Date: Mon, 27 Nov 2017 16:14:49 -0500 Subject: [PATCH] LU-4134 obdclass: fix double free in failure path 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 Change-Id: Ia8d1e487c69c4de1c7c247158cc8615aa6b6093a Reviewed-on: https://review.whamcloud.com/29967 Reviewed-by: Alexey Lyashkov Reviewed-by: James Simmons Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/obdclass/obd_config.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 056ef94..1b735bf 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -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); } } -- 1.8.3.1