Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a9b2e08 authored by Alexander Shishkin's avatar Alexander Shishkin Committed by Greg Kroah-Hartman
Browse files

intel_th: Fix a NULL dereference when hub driver is not loaded



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: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Fixes: 39f40346 ("intel_th: Add driver infrastructure for Intel(R) Trace Hub devices")
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reported-by: default avatarAmmy Yi <ammy.yi@intel.com>
Tested-by: default avatarAmmy Yi <ammy.yi@intel.com>
Cc: stable@vger.kernel.org # v4.4
Link: https://lore.kernel.org/r/20200706161339.55468-5-alexander.shishkin@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ef78159f
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -944,15 +944,30 @@ int intel_th_set_output(struct intel_th_device *thdev,
{
	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);

+1 −3
Original line number Diff line number Diff line
@@ -157,9 +157,7 @@ static int sth_stm_link(struct stm_data *stm_data, unsigned int master,
{
	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)