| From 6fe19127757ad7a3dcb69dc6b20f0ffd45a15086 Mon Sep 17 00:00:00 2001 |
| From: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Date: Thu, 13 Feb 2020 12:56:04 +0300 |
| Subject: [PATCH] thunderbolt: Prevent crash if non-active NVMem file is read |
| |
| commit 03cd45d2e219301880cabc357e3cf478a500080f upstream. |
| |
| The driver does not populate .reg_read callback for the non-active NVMem |
| because the file is supposed to be write-only. However, it turns out |
| NVMem subsystem does not yet support this and expects that the .reg_read |
| callback is provided. If user reads the binary attribute it triggers |
| NULL pointer dereference like this one: |
| |
| BUG: kernel NULL pointer dereference, address: 0000000000000000 |
| ... |
| Call Trace: |
| bin_attr_nvmem_read+0x64/0x80 |
| kernfs_fop_read+0xa7/0x180 |
| vfs_read+0xbd/0x170 |
| ksys_read+0x5a/0xd0 |
| do_syscall_64+0x43/0x150 |
| entry_SYSCALL_64_after_hwframe+0x44/0xa9 |
| |
| Fix this in the driver by providing .reg_read callback that always |
| returns an error. |
| |
| Reported-by: Nicholas Johnson <nicholas.johnson-opensource@outlook.com.au> |
| Fixes: e6b245ccd524 ("thunderbolt: Add support for host and device NVM firmware upgrade") |
| Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/20200213095604.1074-1-mika.westerberg@linux.intel.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c |
| index 416058218b16..e73ae636515f 100644 |
| --- a/drivers/thunderbolt/switch.c |
| +++ b/drivers/thunderbolt/switch.c |
| @@ -274,6 +274,12 @@ static int tb_switch_nvm_read(void *priv, unsigned int offset, void *val, |
| return ret; |
| } |
| |
| +static int tb_switch_nvm_no_read(void *priv, unsigned int offset, void *val, |
| + size_t bytes) |
| +{ |
| + return -EPERM; |
| +} |
| + |
| static int tb_switch_nvm_write(void *priv, unsigned int offset, void *val, |
| size_t bytes) |
| { |
| @@ -319,6 +325,7 @@ static struct nvmem_device *register_nvmem(struct tb_switch *sw, int id, |
| config.read_only = true; |
| } else { |
| config.name = "nvm_non_active"; |
| + config.reg_read = tb_switch_nvm_no_read; |
| config.reg_write = tb_switch_nvm_write; |
| config.root_only = true; |
| } |
| -- |
| 2.7.4 |
| |