[PATCH 4.19 120/133] intel_th: Fix a NULL dereference when hub driver is not loaded

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>

commit e78e1fdb282726beaf88aa75943682217e6ded0e upstream.

Connecting master to an output port when GTH driver module is not loaded
triggers a NULL dereference:

> RIP: 0010:intel_th_set_output+0x35/0x70 [intel_th]
> Call Trace:
>  ? sth_stm_link+0x12/0x20 [intel_th_sth]
>  stm_source_link_store+0x164/0x270 [stm_core]
>  dev_attr_store+0x17/0x30
>  sysfs_kf_write+0x3e/0x50
>  kernfs_fop_write+0xda/0x1b0
>  __vfs_write+0x1b/0x40
>  vfs_write+0xb9/0x1a0
>  ksys_write+0x67/0xe0
>  __x64_sys_write+0x1a/0x20
>  do_syscall_64+0x57/0x1d0
>  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Make sure the module in question is loaded and return an error if not.

Signed-off-by: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
Fixes: 39f4034693b7c ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices")
Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
Reported-by: Ammy Yi <ammy.yi@xxxxxxxxx>
Tested-by: Ammy Yi <ammy.yi@xxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx # v4.4
Link: https://lore.kernel.org/r/20200706161339.55468-5-alexander.shishkin@xxxxxxxxxxxxxxx
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
 drivers/hwtracing/intel_th/core.c |   21 ++++++++++++++++++---
 drivers/hwtracing/intel_th/sth.c  |    4 +---
 2 files changed, 19 insertions(+), 6 deletions(-)

--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -944,15 +944,30 @@ int intel_th_set_output(struct intel_th_
 {
 	struct intel_th_device *hub = to_intel_th_hub(thdev);
 	struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);
+	int ret;
 
 	/* In host mode, this is up to the external debugger, do nothing. */
 	if (hub->host_mode)
 		return 0;
 
-	if (!hubdrv->set_output)
-		return -ENOTSUPP;
+	/*
+	 * hub is instantiated together with the source device that
+	 * calls here, so guaranteed to be present.
+	 */
+	hubdrv = to_intel_th_driver(hub->dev.driver);
+	if (!hubdrv || !try_module_get(hubdrv->driver.owner))
+		return -EINVAL;
 
-	return hubdrv->set_output(hub, master);
+	if (!hubdrv->set_output) {
+		ret = -ENOTSUPP;
+		goto out;
+	}
+
+	ret = hubdrv->set_output(hub, master);
+
+out:
+	module_put(hubdrv->driver.owner);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(intel_th_set_output);
 
--- a/drivers/hwtracing/intel_th/sth.c
+++ b/drivers/hwtracing/intel_th/sth.c
@@ -157,9 +157,7 @@ static int sth_stm_link(struct stm_data
 {
 	struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
 
-	intel_th_set_output(to_intel_th_device(sth->dev), master);
-
-	return 0;
+	return intel_th_set_output(to_intel_th_device(sth->dev), master);
 }
 
 static int intel_th_sw_init(struct sth_device *sth)





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux