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 at intel.com>
> Cc: stable at vger.kernel.org
> Signed-off-by: Xie Yongji <xieyongji at 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