<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/drivers/media/media-devnode.c, branch v4.9.60</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>[media] media: fix media devnode ioctl/syscall and unregister race</title>
<updated>2016-06-15T20:59:28+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuahkh@osg.samsung.com</email>
</author>
<published>2016-06-10T17:37:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=6f0dd24a084a17f9984dd49dffbf7055bf123993'/>
<id>6f0dd24a084a17f9984dd49dffbf7055bf123993</id>
<content type='text'>
Media devnode open/ioctl could be in progress when media device unregister
is initiated. System calls and ioctls check media device registered status
at the beginning, however, there is a window where unregister could be in
progress without changing the media devnode status to unregistered.

process 1				process 2
fd = open(/dev/media0)
media_devnode_is_registered()
	(returns true here)

					media_device_unregister()
						(unregister is in progress
						and devnode isn't
						unregistered yet)
					...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
	(returns true here)
					...
					media_devnode_unregister()
					...
					(driver releases the media device
					memory)

media_device_ioctl()
	(By this point
	devnode-&gt;media_dev does not
	point to allocated memory.
	use-after free in in mutex_lock_nested)

BUG: KASAN: use-after-free in mutex_lock_nested+0x79c/0x800 at addr
ffff8801ebe914f0

Fix it by clearing register bit when unregister starts to avoid the race.

process 1                               process 2
fd = open(/dev/media0)
media_devnode_is_registered()
        (could return true here)

                                        media_device_unregister()
                                                (clear the register bit,
						 then start unregister.)
                                        ...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
        (return false here, ioctl
	 returns I/O error, and
	 will not access media
	 device memory)
                                        ...
                                        media_devnode_unregister()
                                        ...
                                        (driver releases the media device
					 memory)

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Suggested-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Reported-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Tested-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Media devnode open/ioctl could be in progress when media device unregister
is initiated. System calls and ioctls check media device registered status
at the beginning, however, there is a window where unregister could be in
progress without changing the media devnode status to unregistered.

process 1				process 2
fd = open(/dev/media0)
media_devnode_is_registered()
	(returns true here)

					media_device_unregister()
						(unregister is in progress
						and devnode isn't
						unregistered yet)
					...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
	(returns true here)
					...
					media_devnode_unregister()
					...
					(driver releases the media device
					memory)

media_device_ioctl()
	(By this point
	devnode-&gt;media_dev does not
	point to allocated memory.
	use-after free in in mutex_lock_nested)

BUG: KASAN: use-after-free in mutex_lock_nested+0x79c/0x800 at addr
ffff8801ebe914f0

Fix it by clearing register bit when unregister starts to avoid the race.

process 1                               process 2
fd = open(/dev/media0)
media_devnode_is_registered()
        (could return true here)

                                        media_device_unregister()
                                                (clear the register bit,
						 then start unregister.)
                                        ...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
        (return false here, ioctl
	 returns I/O error, and
	 will not access media
	 device memory)
                                        ...
                                        media_devnode_unregister()
                                        ...
                                        (driver releases the media device
					 memory)

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Suggested-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Reported-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Tested-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media: fix use-after-free in cdev_put() when app exits after driver unbind</title>
<updated>2016-06-15T20:58:06+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuahkh@osg.samsung.com</email>
</author>
<published>2016-05-04T19:48:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=5b28dde51d0ccc54cee70756e1800d70bed7114a'/>
<id>5b28dde51d0ccc54cee70756e1800d70bed7114a</id>
<content type='text'>
When driver unbinds while media_ioctl is in progress, cdev_put() fails with
when app exits after driver unbinds.

Add devnode struct device kobj as the cdev parent kobject. cdev_add() gets
a reference to it and releases it in cdev_del() ensuring that the devnode
is not deallocated as long as the application has the device file open.

media_devnode_register() initializes the struct device kobj before calling
cdev_add(). media_devnode_unregister() does cdev_del() and then deletes the
device. devnode is released when the last reference to the struct device is
gone.

This problem is found on uvcvideo, em28xx, and au0828 drivers and fix has
been tested on all three.

kernel: [  193.599736] BUG: KASAN: use-after-free in cdev_put+0x4e/0x50
kernel: [  193.599745] Read of size 8 by task media_device_te/1851
kernel: [  193.599792] INFO: Allocated in __media_device_register+0x54
kernel: [  193.599951] INFO: Freed in media_devnode_release+0xa4/0xc0

kernel: [  193.601083] Call Trace:
kernel: [  193.601093]  [&lt;ffffffff81aecac3&gt;] dump_stack+0x67/0x94
kernel: [  193.601102]  [&lt;ffffffff815359b2&gt;] print_trailer+0x112/0x1a0
kernel: [  193.601111]  [&lt;ffffffff8153b5e4&gt;] object_err+0x34/0x40
kernel: [  193.601119]  [&lt;ffffffff8153d9d4&gt;] kasan_report_error+0x224/0x530
kernel: [  193.601128]  [&lt;ffffffff814a2c3d&gt;] ? kzfree+0x2d/0x40
kernel: [  193.601137]  [&lt;ffffffff81539d72&gt;] ? kfree+0x1d2/0x1f0
kernel: [  193.601154]  [&lt;ffffffff8157ca7e&gt;] ? cdev_put+0x4e/0x50
kernel: [  193.601162]  [&lt;ffffffff8157ca7e&gt;] cdev_put+0x4e/0x50
kernel: [  193.601170]  [&lt;ffffffff815767eb&gt;] __fput+0x52b/0x6c0
kernel: [  193.601179]  [&lt;ffffffff8117743a&gt;] ? switch_task_namespaces+0x2a
kernel: [  193.601188]  [&lt;ffffffff815769ee&gt;] ____fput+0xe/0x10
kernel: [  193.601196]  [&lt;ffffffff81170023&gt;] task_work_run+0x133/0x1f0
kernel: [  193.601204]  [&lt;ffffffff8117746e&gt;] ? switch_task_namespaces+0x5e
kernel: [  193.601213]  [&lt;ffffffff8111b50c&gt;] do_exit+0x72c/0x2c20
kernel: [  193.601224]  [&lt;ffffffff8111ade0&gt;] ? release_task+0x1250/0x1250
-
-
-
kernel: [  193.601360]  [&lt;ffffffff81003587&gt;] ? exit_to_usermode_loop+0xe7
kernel: [  193.601368]  [&lt;ffffffff810035c0&gt;] exit_to_usermode_loop+0x120
kernel: [  193.601376]  [&lt;ffffffff810061da&gt;] syscall_return_slowpath+0x16a
kernel: [  193.601386]  [&lt;ffffffff82848b33&gt;] entry_SYSCALL_64_fastpath+0xa6

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Tested-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When driver unbinds while media_ioctl is in progress, cdev_put() fails with
when app exits after driver unbinds.

Add devnode struct device kobj as the cdev parent kobject. cdev_add() gets
a reference to it and releases it in cdev_del() ensuring that the devnode
is not deallocated as long as the application has the device file open.

media_devnode_register() initializes the struct device kobj before calling
cdev_add(). media_devnode_unregister() does cdev_del() and then deletes the
device. devnode is released when the last reference to the struct device is
gone.

This problem is found on uvcvideo, em28xx, and au0828 drivers and fix has
been tested on all three.

kernel: [  193.599736] BUG: KASAN: use-after-free in cdev_put+0x4e/0x50
kernel: [  193.599745] Read of size 8 by task media_device_te/1851
kernel: [  193.599792] INFO: Allocated in __media_device_register+0x54
kernel: [  193.599951] INFO: Freed in media_devnode_release+0xa4/0xc0

kernel: [  193.601083] Call Trace:
kernel: [  193.601093]  [&lt;ffffffff81aecac3&gt;] dump_stack+0x67/0x94
kernel: [  193.601102]  [&lt;ffffffff815359b2&gt;] print_trailer+0x112/0x1a0
kernel: [  193.601111]  [&lt;ffffffff8153b5e4&gt;] object_err+0x34/0x40
kernel: [  193.601119]  [&lt;ffffffff8153d9d4&gt;] kasan_report_error+0x224/0x530
kernel: [  193.601128]  [&lt;ffffffff814a2c3d&gt;] ? kzfree+0x2d/0x40
kernel: [  193.601137]  [&lt;ffffffff81539d72&gt;] ? kfree+0x1d2/0x1f0
kernel: [  193.601154]  [&lt;ffffffff8157ca7e&gt;] ? cdev_put+0x4e/0x50
kernel: [  193.601162]  [&lt;ffffffff8157ca7e&gt;] cdev_put+0x4e/0x50
kernel: [  193.601170]  [&lt;ffffffff815767eb&gt;] __fput+0x52b/0x6c0
kernel: [  193.601179]  [&lt;ffffffff8117743a&gt;] ? switch_task_namespaces+0x2a
kernel: [  193.601188]  [&lt;ffffffff815769ee&gt;] ____fput+0xe/0x10
kernel: [  193.601196]  [&lt;ffffffff81170023&gt;] task_work_run+0x133/0x1f0
kernel: [  193.601204]  [&lt;ffffffff8117746e&gt;] ? switch_task_namespaces+0x5e
kernel: [  193.601213]  [&lt;ffffffff8111b50c&gt;] do_exit+0x72c/0x2c20
kernel: [  193.601224]  [&lt;ffffffff8111ade0&gt;] ? release_task+0x1250/0x1250
-
-
-
kernel: [  193.601360]  [&lt;ffffffff81003587&gt;] ? exit_to_usermode_loop+0xe7
kernel: [  193.601368]  [&lt;ffffffff810035c0&gt;] exit_to_usermode_loop+0x120
kernel: [  193.601376]  [&lt;ffffffff810061da&gt;] syscall_return_slowpath+0x16a
kernel: [  193.601386]  [&lt;ffffffff82848b33&gt;] entry_SYSCALL_64_fastpath+0xa6

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Tested-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media-device: dynamically allocate struct media_devnode</title>
<updated>2016-06-15T20:57:24+00:00</updated>
<author>
<name>Mauro Carvalho Chehab</name>
<email>mchehab@osg.samsung.com</email>
</author>
<published>2016-04-27T22:28:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=a087ce704b802becbb4b0f2a20f2cb3f6911802e'/>
<id>a087ce704b802becbb4b0f2a20f2cb3f6911802e</id>
<content type='text'>
struct media_devnode is currently embedded at struct media_device.

While this works fine during normal usage, it leads to a race
condition during devnode unregister. the problem is that drivers
assume that, after calling media_device_unregister(), the struct
that contains media_device can be freed. This is not true, as it
can't be freed until userspace closes all opened /dev/media devnodes.

In other words, if the media devnode is still open, and media_device
gets freed, any call to an ioctl will make the core to try to access
struct media_device, with will cause an use-after-free and even GPF.

Fix this by dynamically allocating the struct media_devnode and only
freeing it when it is safe.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
struct media_devnode is currently embedded at struct media_device.

While this works fine during normal usage, it leads to a race
condition during devnode unregister. the problem is that drivers
assume that, after calling media_device_unregister(), the struct
that contains media_device can be freed. This is not true, as it
can't be freed until userspace closes all opened /dev/media devnodes.

In other words, if the media devnode is still open, and media_device
gets freed, any call to an ioctl will make the core to try to access
struct media_device, with will cause an use-after-free and even GPF.

Fix this by dynamically allocating the struct media_devnode and only
freeing it when it is safe.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media-devnode: fix namespace mess</title>
<updated>2016-06-15T20:56:06+00:00</updated>
<author>
<name>Mauro Carvalho Chehab</name>
<email>mchehab@osg.samsung.com</email>
</author>
<published>2016-03-23T14:22:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=163f1e93e995048b894c5fc86a6034d16beed740'/>
<id>163f1e93e995048b894c5fc86a6034d16beed740</id>
<content type='text'>
Along all media controller code, "mdev" is used to represent
a pointer to struct media_device, and "devnode" for a pointer
to struct media_devnode.

However, inside media-devnode.[ch], "mdev" is used to represent
a pointer to struct media_devnode.

This is very confusing and may lead to development errors.

So, let's change all occurrences at media-devnode.[ch] to
also use "devnode" for such pointers.

This patch doesn't make any functional changes.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Along all media controller code, "mdev" is used to represent
a pointer to struct media_device, and "devnode" for a pointer
to struct media_devnode.

However, inside media-devnode.[ch], "mdev" is used to represent
a pointer to struct media_devnode.

This is very confusing and may lead to development errors.

So, let's change all occurrences at media-devnode.[ch] to
also use "devnode" for such pointers.

This patch doesn't make any functional changes.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@s-opensource.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] drivers/media/media-devnode: clear private_data before put_device()</title>
<updated>2016-05-07T14:43:53+00:00</updated>
<author>
<name>Max Kellermann</name>
<email>max@duempel.org</email>
</author>
<published>2016-03-21T13:30:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=bf244f665d76d20312c80524689b32a752888838'/>
<id>bf244f665d76d20312c80524689b32a752888838</id>
<content type='text'>
Callbacks invoked from put_device() may free the struct media_devnode
pointer, so any cleanup needs to be done before put_device().

Signed-off-by: Max Kellermann &lt;max@duempel.org&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Callbacks invoked from put_device() may free the struct media_devnode
pointer, so any cleanup needs to be done before put_device().

Signed-off-by: Max Kellermann &lt;max@duempel.org&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media-devnode: add missing mutex lock in error handler</title>
<updated>2016-04-06T12:39:56+00:00</updated>
<author>
<name>Max Kellermann</name>
<email>max@duempel.org</email>
</author>
<published>2016-03-21T11:33:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=88336e174645948da269e1812f138f727cd2896b'/>
<id>88336e174645948da269e1812f138f727cd2896b</id>
<content type='text'>
We should protect the device unregister patch too, at the error
condition.

Signed-off-by: Max Kellermann &lt;max@duempel.org&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We should protect the device unregister patch too, at the error
condition.

Signed-off-by: Max Kellermann &lt;max@duempel.org&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media: Fix media_open() to clear filp-&gt;private_data in error leg</title>
<updated>2016-02-01T15:21:33+00:00</updated>
<author>
<name>Shuah Khan</name>
<email>shuahkh@osg.samsung.com</email>
</author>
<published>2016-01-27T23:49:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=d40ec6fdb0b03b7be4c7923a3da0e46bf943740a'/>
<id>d40ec6fdb0b03b7be4c7923a3da0e46bf943740a</id>
<content type='text'>
Fix media_open() to clear filp-&gt;private_data when file open
fails.

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Acked-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fix media_open() to clear filp-&gt;private_data when file open
fails.

Signed-off-by: Shuah Khan &lt;shuahkh@osg.samsung.com&gt;
Acked-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media-devnode: move kernel-doc documentation to the header</title>
<updated>2016-01-11T14:19:13+00:00</updated>
<author>
<name>Mauro Carvalho Chehab</name>
<email>mchehab@osg.samsung.com</email>
</author>
<published>2015-12-13T10:40:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=fe3c565e4cbcb2adeef063accc7852de739aaa36'/>
<id>fe3c565e4cbcb2adeef063accc7852de739aaa36</id>
<content type='text'>
As we're using the headers file only for documentation, move the
two kernel-doc macros to the header, and fix it to avoid
warnings.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As we're using the headers file only for documentation, move the
two kernel-doc macros to the header, and fix it to avoid
warnings.

Signed-off-by: Mauro Carvalho Chehab &lt;mchehab@osg.samsung.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media-devnode: just return 0 instead of using a var</title>
<updated>2014-09-03T20:59:28+00:00</updated>
<author>
<name>Mauro Carvalho Chehab</name>
<email>m.chehab@samsung.com</email>
</author>
<published>2014-09-03T18:18:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=8b37c6455fc8f43e0e95db2847284e618db6a4f8'/>
<id>8b37c6455fc8f43e0e95db2847284e618db6a4f8</id>
<content type='text'>
Instead of allocating a var to store 0 and just return it,
change the code to return 0 directly.

Signed-off-by: Mauro Carvalho Chehab &lt;m.chehab@samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Instead of allocating a var to store 0 and just return it,
change the code to return 0 directly.

Signed-off-by: Mauro Carvalho Chehab &lt;m.chehab@samsung.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>[media] media: Use a better owner for the media device</title>
<updated>2014-05-13T16:39:00+00:00</updated>
<author>
<name>Sakari Ailus</name>
<email>sakari.ailus@linux.intel.com</email>
</author>
<published>2013-12-12T15:38:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=85de721c46ba8ad9b283b2b3e307c9a3e8425042'/>
<id>85de721c46ba8ad9b283b2b3e307c9a3e8425042</id>
<content type='text'>
mdev-&gt;fops-&gt;owner is actually the owner of the very same module which
implements media_device_register(), so it can't be unloaded anyway. Instead,
use THIS_MODULE through a macro as does video_register_device().

Signed-off-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Acked-by: Laurent Pinchart &lt;laurent.pinchart@ideasonboard.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;m.chehab@samsung.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
mdev-&gt;fops-&gt;owner is actually the owner of the very same module which
implements media_device_register(), so it can't be unloaded anyway. Instead,
use THIS_MODULE through a macro as does video_register_device().

Signed-off-by: Sakari Ailus &lt;sakari.ailus@linux.intel.com&gt;
Acked-by: Laurent Pinchart &lt;laurent.pinchart@ideasonboard.com&gt;
Signed-off-by: Mauro Carvalho Chehab &lt;m.chehab@samsung.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
