A potential race
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 16 lines · Pavel Andrianov
Hi!
There is a potential race condition between
usbvision_v4l2_close
<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L403> andusbvision_disconnect
<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1569>. The possible scenario may be the following.usbvision_disconnect<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1569> starts execution, assignsusbvision->remove_pending= 1 <http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1587>, and is interrupted (rescheduled) aftermutex_unlock<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1592>. After thatusbvision_v4l2_close<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L403> is executed, decrease usbvision->user-- <http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L419>, checksusbvision->remove_pending<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L422>, executesusbvision_release<http://lxr.free-electrons.com/ident?i=usbvision_release> and finishes. Thenusbvision_disconnect
<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1569> continues its execution. It checksusbversion->user<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1594> (it is already 0) and also executeusbvision_release<http://lxr.free-electrons.com/ident?i=usbvision_release>. Thus, release is executed twice. The same situation may occur ifusbvision_v4l2_close<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L403> is interrupted by
Quoted 8 lines
usbvision_disconnect<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1569>. Moreover, the same problem is inusbvision_radio_close<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1135>. In all these cases the check before callusbvision_release<http://lxr.free-electrons.com/ident?i=usbvision_release> undermutex_lockprotection does not solve the problem, because there may occur anopen()after the check and the race takes place again. The question is: why theusbvision_release
<http://lxr.free-electrons.com/ident?i=usbvision_release> is called fromclose()(usbvision_v4l2_close
<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L403> andusbvision_radio_close
<http://lxr.free-electrons.com/source/drivers/media/usb/usbvision/usbvision-video.c#L1135>)? Usually release functions are called from disconnect.
Please don't use html mail, mailinglists will silently reject this.
The usbvision driver is old and unloved and known to be very bad code. It needs a huge amount of work to make all this work correctly.
I don't see anyone picking this up...
Regards,
Hans
01.07.2016 19:53, Hans Verkuil пишет:
Quoted 11 lines · Pavel Andrianov
Quoted 8 lines
Hi!
There is a potential race condition between
usbvision_v4l2_closeandusbvision_disconnect. The possible scenario may be the following.usbvision_disconnectstarts execution, assignsusbvision->remove_pending= 1, and is interrupted
(rescheduled) aftermutex_unlock. After thatusbvision_v4l2_closeis executed, decrease usbvision->user-- , checksusbvision->remove_pending, executesusbvision_releaseand finishes. Thenusbvision_disconnectcontinues its execution. It checksusbversion->user(it is already 0) and also executeusbvision_release. Thus, release is executed twice. The same situation may
occur ifusbvision_v4l2_closeis interrupted byusbvision_disconnect. Moreover, the same problem is inusbvision_radio_close. In all these cases the check before callusbvision_releaseundermutex_lockprotection does not solve the problem, because there may occur anopen()after the check and the race takes place again. The question is: why theusbvision_releaseis called fromclose()(usbvision_v4l2_closeandusbvision_radio_close)? Usually release functions are called from
disconnect.Please don't use html mail, mailinglists will silently reject this.
Quoted 7 lines
The usbvision driver is old and unloved and known to be very bad code. It needs a huge amount of work to make all this work correctly.
I don't see anyone picking this up...
Regards,
Hans
If you know the driver, could you, please, explain me, why usbvision_release is called from close functions (usbvision_v4l2_close and usbvision_radio_close) and not only from disconnect? Thanks!
Signature · 4 lines
Pavel Andrianov Linux Verification Center, ISPRAS web: http://linuxtesting.org e-mail: [email protected]
Quoted 14 lines · Pavel Andrianov
01.07.2016 19:53, Hans Verkuil пишет:
Quoted 13 lines · Pavel Andrianov
Quoted 8 lines
Hi!
There is a potential race condition between
usbvision_v4l2_closeandusbvision_disconnect. The possible scenario may be the following.usbvision_disconnectstarts execution, assignsusbvision->remove_pending= 1, and is interrupted
(rescheduled) aftermutex_unlock. After thatusbvision_v4l2_closeis executed, decrease usbvision->user-- , checksusbvision->remove_pending, executesusbvision_releaseand finishes. Thenusbvision_disconnectcontinues its execution. It checksusbversion->user(it is already 0) and also executeusbvision_release. Thus, release is executed twice. The same situation may
occur ifusbvision_v4l2_closeis interrupted byusbvision_disconnect. Moreover, the same problem is inusbvision_radio_close. In all these cases the check before callusbvision_releaseundermutex_lockprotection does not solve the problem, because there may occur anopen()after the check and the race takes place again. The question is: why theusbvision_releaseis called fromclose()(usbvision_v4l2_closeandusbvision_radio_close)? Usually release functions are called from
disconnect.Please don't use html mail, mailinglists will silently reject this.
The usbvision driver is old and unloved and known to be very bad code. It needs a huge amount of work to make all this work correctly.
Quoted 9 lines
Quoted 5 lines
I don't see anyone picking this up...
Regards,
Hans
If you know the driver, could you, please, explain me, why
usbvision_releaseis called from close functions (usbvision_v4l2_closeandusbvision_radio_close) and not only from disconnect? Thanks!
Because the author didn't know what he was doing. Although, to be fair, we have much better solutions for this. But who is willing to put in the time to fix this properly?
The basic idea was: if someone still has a video/radio node open when disconnect happens, then we leave it to the last close to call release, otherwise we can call release right away.
It needs to be rewritten.
If you're volunteering to clean this up, then I can give pointers.
Regards,
Hans
Hi!
We have no hardware to test possible fixes. If somebody has it and agrees to check our patches, we will prepare them.
Best regards,
Pavel
01.07.2016 20:17, Hans Verkuil пишет:
Quoted 37 lines · Pavel Andrianov
Quoted 14 lines
01.07.2016 19:53, Hans Verkuil пишет:
Quoted 13 lines · Pavel Andrianov
Quoted 8 lines
Hi!There is a potential race condition between
usbvision_v4l2_closeandusbvision_disconnect. The possible scenario may be the following.usbvision_disconnectstarts execution, assignsusbvision->remove_pending= 1, and is interrupted
(rescheduled) aftermutex_unlock. After thatusbvision_v4l2_closeis executed, decrease usbvision->user-- , checksusbvision->remove_pending, executesusbvision_releaseand finishes. Thenusbvision_disconnectcontinues its execution. It checksusbversion->user(it is already 0) and also executeusbvision_release. Thus, release is executed twice. The same situation may
occur ifusbvision_v4l2_closeis interrupted byusbvision_disconnect. Moreover, the same problem is inusbvision_radio_close. In all these cases the check before callusbvision_releaseundermutex_lockprotection does not solve the problem, because there may occur anopen()after the check and the race takes place again. The question is: why theusbvision_releaseis called fromclose()(usbvision_v4l2_closeandusbvision_radio_close)? Usually release functions are called from
disconnect.Please don't use html mail, mailinglists will silently reject this.
The usbvision driver is old and unloved and known to be very bad code. It needs a huge amount of work to make all this work correctly.
Quoted 9 lines
Quoted 5 lines
I don't see anyone picking this up...
Regards,
Hans
If you know the driver, could you, please, explain me, why
usbvision_releaseis called from close functions (usbvision_v4l2_closeandusbvision_radio_close) and not only from disconnect? Thanks!Because the author didn't know what he was doing. Although, to be fair, we have much better solutions for this. But who is willing to put in the time to fix this properly?
The basic idea was: if someone still has a video/radio node open when disconnect happens, then we leave it to the last close to call release, otherwise we can call release right away.
It needs to be rewritten.
If you're volunteering to clean this up, then I can give pointers.
Regards,
Hans
Signature · 4 lines
Pavel Andrianov Linux Verification Center, ISPRAS web: http://linuxtesting.org e-mail: [email protected]