<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>This is a NULL pointer derefrence bug in USB_ZR364XX driver.</p>
<p><a
href="https://syzkaller.appspot.com/bug?id=9c0c178c24d828a7378f483309001329750aad64"
style="font-family: "Times New Roman"; font-size:
medium; font-style: normal; font-variant-ligatures: normal;
font-variant-caps: normal; font-weight: 400; letter-spacing:
normal; orphans: 2; text-align: start; text-indent: 0px;
text-transform: none; white-space: nowrap; widows: 2;
word-spacing: 0px; -webkit-text-stroke-width: 0px;
background-color: rgb(255, 255, 153);">KASAN: null-ptr-deref
Read in zr364xx_vidioc_querycap</a></p>
<p><br>
The ioctl vidioc_querycap() is used to get capablity of driver and
hardware.<br>
USB_ZR364XX driver registers zr364xx_vidioc_querycap() as
.vidioc_querycap funtion which is part of v4l2_ioctl_ops in v4l2.<br>
When VIDIOC_QUERYCAP ioctl is called, the below function path is
traversed<br>
<br>
v4l2_ioctl()->video_usercopy()->__video_do_ioctl()->v4l_querycap()->zr364xx_vidioc_querycap()<br>
<br>
which further calls below funtions<br>
<br>
strcpy()->read_word_at_a_time()->kasan_check_read()->check_memory_region()->check_memory_region_inline->kasan_report().<br>
<br>
In function check_memory_region(), if the input addr is not valid,
that is,<br>
if addr is greater than KASAN_SHADOW_START which is VA_START - the
first kernel virtual address.<br>
then, kasan_report() get called which prints the stack seen in bug
report via dump_stack().<br>
<br>
The stack trace in the bug points at below line in
zr364xx_vidioc_querycap()<br>
<br>
"706 strscpy(cap->card, cam->udev->product,
sizeof(cap->card));"<br>
<br>
The bug report has the below line which tells that the addr which
is src(cam->udev->product) in the above strcpy() is NULL.<br>
<br>
"Read of size 1 at addr 0000000000000000 by task v4l_id/5287"<br>
<br>
So, for this device the Product is not initialized and accessing
it causes a NULL pointer deref.<br>
<br>
Also, in usb.h in comment on struct usb_device it says<br>
"@product: iProduct string, if present (static)" .<br>
I deduce that product can be NULL from this, and in all other
places where udev->product is accessed does NULL check before
accessing it.<br>
<br>
The fix would be to check for NULL before strcpy or/and copy
DRIVER_DESC or "zr364xx" to cap->card insted in
zr364xx_vidioc_querycap().<br>
<br>
I could not reproduce this as i dont have the device to test it.</p>
<p>Please let me know your feedback.<br>
</p>
<p>Thanks,</p>
<p>Vandana.<br>
</p>
</body>
</html>