The control device has no drvdata. So we will get a NULL NULL pointer dereference when accessing control device's msg_timeout via sysfs:
[ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419)
To fix it, let's add a NULL check in msg_timeout_show() and msg_timeout_store().
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji xieyongji@bytedance.com --- drivers/vdpa/vdpa_user/vduse_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index f85d1a08ed87..f1c42f4aabb4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1268,6 +1268,9 @@ static ssize_t msg_timeout_show(struct device *device, { struct vduse_dev *dev = dev_get_drvdata(device);
+ if (!dev) + return -EPERM; + return sysfs_emit(buf, "%u\n", dev->msg_timeout); }
@@ -1278,6 +1281,9 @@ static ssize_t msg_timeout_store(struct device *device, struct vduse_dev *dev = dev_get_drvdata(device); int ret;
+ if (!dev) + return -EPERM; + ret = kstrtouint(buf, 10, &dev->msg_timeout); if (ret < 0) return ret;
On Tue, Apr 26, 2022 at 2:01 PM Xie Yongji xieyongji@bytedance.com wrote:
The control device has no drvdata. So we will get a NULL NULL pointer dereference when accessing control device's msg_timeout via sysfs:
[ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419)
To fix it, let's add a NULL check in msg_timeout_show() and msg_timeout_store().
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji xieyongji@bytedance.com
drivers/vdpa/vdpa_user/vduse_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index f85d1a08ed87..f1c42f4aabb4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1268,6 +1268,9 @@ static ssize_t msg_timeout_show(struct device *device, { struct vduse_dev *dev = dev_get_drvdata(device);
if (!dev)
return -EPERM;
I wonder if it's possible to not have those attributes for the control device.
Thanks
return sysfs_emit(buf, "%u\n", dev->msg_timeout);
}
@@ -1278,6 +1281,9 @@ static ssize_t msg_timeout_store(struct device *device, struct vduse_dev *dev = dev_get_drvdata(device); int ret;
if (!dev)
return -EPERM;
ret = kstrtouint(buf, 10, &dev->msg_timeout); if (ret < 0) return ret;
-- 2.20.1
On Tue, Apr 26, 2022 at 2:19 PM Jason Wang jasowang@redhat.com wrote:
On Tue, Apr 26, 2022 at 2:01 PM Xie Yongji xieyongji@bytedance.com wrote:
The control device has no drvdata. So we will get a NULL NULL pointer dereference when accessing control device's msg_timeout via sysfs:
[ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419)
To fix it, let's add a NULL check in msg_timeout_show() and msg_timeout_store().
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji xieyongji@bytedance.com
drivers/vdpa/vdpa_user/vduse_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index f85d1a08ed87..f1c42f4aabb4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1268,6 +1268,9 @@ static ssize_t msg_timeout_show(struct device *device, { struct vduse_dev *dev = dev_get_drvdata(device);
if (!dev)
return -EPERM;
I wonder if it's possible to not have those attributes for the control device.
Yes, I think we can. Will do it in v2.
Thanks, Yongji
On Tue, Apr 26, 2022 at 02:01:03PM +0800, Xie Yongji wrote:
The control device has no drvdata. So we will get a NULL NULL pointer dereference when accessing control device's msg_timeout via sysfs:
[ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419)
To fix it, let's add a NULL check in msg_timeout_show() and msg_timeout_store().
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji xieyongji@bytedance.com
drivers/vdpa/vdpa_user/vduse_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index f85d1a08ed87..f1c42f4aabb4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1268,6 +1268,9 @@ static ssize_t msg_timeout_show(struct device *device, { struct vduse_dev *dev = dev_get_drvdata(device);
- if (!dev)
return -EPERM;
- return sysfs_emit(buf, "%u\n", dev->msg_timeout);
What prevents the pointer from going away right after you checked it if this is something that changes over time?
If this attribute is never going to be valid for this device, just do not create it.
thanks,
greg k-h
On Tue, Apr 26, 2022 at 2:31 PM Greg KH gregkh@linuxfoundation.org wrote:
On Tue, Apr 26, 2022 at 02:01:03PM +0800, Xie Yongji wrote:
The control device has no drvdata. So we will get a NULL NULL pointer dereference when accessing control device's msg_timeout via sysfs:
[ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419)
To fix it, let's add a NULL check in msg_timeout_show() and msg_timeout_store().
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji xieyongji@bytedance.com
drivers/vdpa/vdpa_user/vduse_dev.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index f85d1a08ed87..f1c42f4aabb4 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1268,6 +1268,9 @@ static ssize_t msg_timeout_show(struct device *device, { struct vduse_dev *dev = dev_get_drvdata(device);
if (!dev)
return -EPERM;
return sysfs_emit(buf, "%u\n", dev->msg_timeout);
What prevents the pointer from going away right after you checked it if this is something that changes over time?
If this attribute is never going to be valid for this device, just do not create it.
Got it. Will fix it in v2.
Thanks, Yongji
linux-stable-mirror@lists.linaro.org