[PATCH linux dev-5.1] fsi: core: Fix NULL dereference issue

Lei YU mine260309 at gmail.com
Fri Jun 14 17:16:43 AEST 2019


The failure case in fsi_slave_init() is wrong and could cause NULL
dereference issue.
E.g. on FP5280G2 machine, it could get failure in fsi_slave_set_smode(),
and when it does fsi rescan, kernel crashes due to:

    Unable to handle kernel NULL pointer dereference at virtual address 00000060

The fix is to make it not calling kfree() but just goto err_free.

However, in err_free, it calls put_device() to free the device, it still
cause issue during fsi rescan, that the device is used after freed.

    WARNING: CPU: 0 PID: 1433 at lib/refcount.c:190 refcount_sub_and_test_checked+0x94/0xac
    refcount_t: underflow; use-after-free.

So the put_device() is removed and "err_free" label is renamed to "fail".

The slave device is freed by put_device() in fsi_master_remove_slave().

Signed-off-by: Lei YU <mine260309 at gmail.com>
---
 drivers/fsi/fsi-core.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 2c31563fdcae..ebede90cf4bd 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -1041,14 +1041,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 	rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt,
 				 &slave->cdev_idx);
 	if (rc)
-		goto err_free;
+		goto fail;
 
 	/* Create chardev for userspace access */
 	cdev_init(&slave->cdev, &cfam_fops);
 	rc = cdev_device_add(&slave->cdev, &slave->dev);
 	if (rc) {
 		dev_err(&slave->dev, "Error %d creating slave device\n", rc);
-		goto err_free;
+		goto fail;
 	}
 
 	rc = fsi_slave_set_smode(slave);
@@ -1056,8 +1056,8 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 		dev_warn(&master->dev,
 				"can't set smode on slave:%02x:%02x %d\n",
 				link, id, rc);
-		kfree(slave);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto fail;
 	}
 	if (master->link_config)
 		master->link_config(master, link,
@@ -1075,10 +1075,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
 		dev_dbg(&master->dev, "failed during slave scan with: %d\n",
 				rc);
 
-	return rc;
-
- err_free:
-	put_device(&slave->dev);
+ fail:
 	return rc;
 }
 
-- 
2.17.1



More information about the openbmc mailing list