diff options
author | Dennis Dalessandro <dennis.dalessandro@intel.com> | 2016-05-19 05:26:44 -0700 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-05-26 11:35:13 -0400 |
commit | e11ffbd57520c3832e05f2f5f19e9ff6adbb7cdc (patch) | |
tree | 6926bb60c32447ffc09e68e909492d85c0044c38 /drivers/staging/rdma/hfi1/device.c | |
parent | IB/hfi1: Add trace message in user IOCTL handling (diff) | |
download | linux-dev-e11ffbd57520c3832e05f2f5f19e9ff6adbb7cdc.tar.xz linux-dev-e11ffbd57520c3832e05f2f5f19e9ff6adbb7cdc.zip |
IB/hfi1: Do not free hfi1 cdev parent structure early
The deletion of a cdev is not a fence for holding off references to the
structure. The driver attempts to delete the cdev and then proceeds to
free the parent structure, the hfi1_devdata, or dd. This can potentially
lead to a kernel panic in situations where a user has an FD for the cdev
open, and the pci device gets removed. If the user then closes the FD
there will be a NULL dereference when trying to do put on the cdev's
kobject.
Fix this by pointing the cdev's kobject.parent at a new kobject embedded
in its parent structure. Also take a reference when the device is opened
and put it back when it is closed.
Reviewed-by: Mitko Haralanov <mitko.haralanov@intel.com>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/staging/rdma/hfi1/device.c')
-rw-r--r-- | drivers/staging/rdma/hfi1/device.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/staging/rdma/hfi1/device.c b/drivers/staging/rdma/hfi1/device.c index 6ee800f0359f..bf64b5a7bfd7 100644 --- a/drivers/staging/rdma/hfi1/device.c +++ b/drivers/staging/rdma/hfi1/device.c @@ -60,7 +60,8 @@ static dev_t hfi1_dev; int hfi1_cdev_init(int minor, const char *name, const struct file_operations *fops, struct cdev *cdev, struct device **devp, - bool user_accessible) + bool user_accessible, + struct kobject *parent) { const dev_t dev = MKDEV(MAJOR(hfi1_dev), minor); struct device *device = NULL; @@ -68,6 +69,7 @@ int hfi1_cdev_init(int minor, const char *name, cdev_init(cdev, fops); cdev->owner = THIS_MODULE; + cdev->kobj.parent = parent; kobject_set_name(&cdev->kobj, name); ret = cdev_add(cdev, dev, 1); |