__devm_create_dev_dax() invokes kref_get(), which increases the refcount
of the "dax_region".

The reference counting issue happens in several exception handling paths
of __devm_create_dev_dax(). When those error scenarios occur such as add
device failed, the function forgets to decrease the refcnt increased by
kref_get(), causing a refcnt leak.

Fix this issue by calling kref_put() when those error scenarios occur.

Signed-off-by: Xiyu Yang <xiyuyan...@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin....@gmail.com>
---
 drivers/dax/bus.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
index df238c8b6ef2..1a861d90321f 100644
--- a/drivers/dax/bus.c
+++ b/drivers/dax/bus.c
@@ -452,12 +452,15 @@ struct dev_dax *__devm_create_dev_dax(struct dax_region 
*dax_region, int id,
        if (rc) {
                kill_dev_dax(dev_dax);
                put_device(dev);
+               kref_put(&dax_region->kref, dax_region_free);
                return ERR_PTR(rc);
        }
 
        rc = devm_add_action_or_reset(dax_region->dev, unregister_dev_dax, dev);
-       if (rc)
+       if (rc) {
+               kref_put(&dax_region->kref, dax_region_free);
                return ERR_PTR(rc);
+       }
 
        return dev_dax;
 
-- 
2.7.4

Reply via email to