[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