Skip to content

Commit 8ae2f2b

Browse files
Reka NormanJiri Kosina
authored andcommitted
HID: intel-ish-hid: ipc: Fix potential use-after-free in work function
When a reset notify IPC message is received, the ISR schedules a work function and passes the ISHTP device to it via a global pointer ishtp_dev. If ish_probe() fails, the devm-managed device resources including ishtp_dev are freed, but the work is not cancelled, causing a use-after-free when the work function tries to access ishtp_dev. Use devm_work_autocancel() instead, so that the work is automatically cancelled if probe fails. Signed-off-by: Reka Norman <[email protected]> Acked-by: Srinivas Pandruvada <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent db50f7a commit 8ae2f2b

File tree

1 file changed

+8
-1
lines changed
  • drivers/hid/intel-ish-hid/ipc

1 file changed

+8
-1
lines changed

drivers/hid/intel-ish-hid/ipc/ipc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (c) 2014-2016, Intel Corporation.
66
*/
77

8+
#include <linux/devm-helpers.h>
89
#include <linux/sched.h>
910
#include <linux/spinlock.h>
1011
#include <linux/delay.h>
@@ -621,7 +622,6 @@ static void recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
621622
case MNG_RESET_NOTIFY:
622623
if (!ishtp_dev) {
623624
ishtp_dev = dev;
624-
INIT_WORK(&fw_reset_work, fw_reset_work_fn);
625625
}
626626
schedule_work(&fw_reset_work);
627627
break;
@@ -940,6 +940,7 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
940940
{
941941
struct ishtp_device *dev;
942942
int i;
943+
int ret;
943944

944945
dev = devm_kzalloc(&pdev->dev,
945946
sizeof(struct ishtp_device) + sizeof(struct ish_hw),
@@ -975,6 +976,12 @@ struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
975976
list_add_tail(&tx_buf->link, &dev->wr_free_list);
976977
}
977978

979+
ret = devm_work_autocancel(&pdev->dev, &fw_reset_work, fw_reset_work_fn);
980+
if (ret) {
981+
dev_err(dev->devc, "Failed to initialise FW reset work\n");
982+
return NULL;
983+
}
984+
978985
dev->ops = &ish_hw_ops;
979986
dev->devc = &pdev->dev;
980987
dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);

0 commit comments

Comments
 (0)