linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] i2c: core: Prevent race condition when removing i2c devices
@ 2017-06-08  2:43 David Thomson
  2017-06-19 14:36 ` Wolfram Sang
  0 siblings, 1 reply; 9+ messages in thread
From: David Thomson @ 2017-06-08  2:43 UTC (permalink / raw)
  To: linux-i2c; +Cc: wsa, David Thomson

There's a race condition that occurs when deleting & closing multiple
i2c devices, which results in a kernel warning on an incorrect reference
count:

Call Trace:
[c00000007e2cfaf0] [c0000000000b84e4] .module_put+0x24/0xb0 (unreliable)
[c00000007e2cfb70] [c0000000005db830] .i2c_put_adapter+0x30/0x50
[c00000007e2cfbf0] [c0000000005deb74] .i2cdev_release+0x24/0x60
[c00000007e2cfc70] [c00000000014015c] .__fput+0xbc/0x290
[c00000007e2cfd10] [c000000000059b64] .task_work_run+0xf4/0x130
[c00000007e2cfdb0] [c00000000000a0a4] .do_notify_resume+0x74/0x80
[c00000007e2cfe30] [c000000000000acc] .ret_from_except_lite+0x78/0x7c

The race is seen when an i2c adapter is being deleted while
file descriptor on another i2c adapter is being closed. The following
shows two threads executing concurrently (the first number is the thread
id):

4580 i2c_del_mux_adapter adapter i2c-6-mux (chan_id 2)
4580 i2c_del_adapter adapter i2c-6-mux (chan_id 2)
4580 i2cdev_detach_adapter adapter i2c-6-mux (chan_id 2)
2627 i2cdev_release START adapter i2c-6-mux (chan_id 2)
2627 i2c_put_adapter START adapter i2c-6-mux (chan_id 2) owner (null)
2627 i2c_adapter_dev_release adapter i2c-6-mux (chan_id 2)
4580 i2c_del_mux_adapter adapter i2c-6-mux (chan_id 3)
4580 i2c_del_adapter adapter i2c-6-mux (chan_id 3)
4580 i2cdev_detach_adapter adapter i2c-6-mux (chan_id 3)
2627 i2c_put_adapter END adapter i2c-6-mux (chan_id 2) owner c0000000edf66400
2627 i2cdev_release END adapter i2c-6-mux (chan_id 2)
2627 i2cdev_release START adapter i2c-6-mux (chan_id 3)
2627 i2c_put_adapter START adapter i2c-6-mux (chan_id 3) owner (null)
2627 i2c_adapter_dev_release adapter i2c-6-mux (chan_id 3)
2627 i2c_put_adapter END adapter i2c-6-mux (chan_id 3) owner (null)
2627 i2cdev_release END adapter i2c-6-mux (chan_id 3)

When thread 4580 for chan_id 3 interrupts 2627 doing
i2c_adapter_dev_release, the 'owner' field for chan_id 2 becomes
non-null. This causes the code to attempt to decrement the reference for
this owner, but the current reference count is invalid. I'm not sure how
the owner is getting set, but adding a lock around the
put_device/module_put calls resolves the issue.

Signed-off-by: David Thomson <david.thomson@alliedtelesis.co.nz>
---
 drivers/i2c/i2c-core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 82576aaccc90..8831d9b363a7 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -3151,8 +3151,12 @@ void i2c_put_adapter(struct i2c_adapter *adap)
 	if (!adap)
 		return;
 
+	mutex_lock(&core_lock);
+
 	put_device(&adap->dev);
 	module_put(adap->owner);
+
+	mutex_unlock(&core_lock);
 }
 EXPORT_SYMBOL(i2c_put_adapter);
 
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-08-18  8:04 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-08  2:43 [PATCH] i2c: core: Prevent race condition when removing i2c devices David Thomson
2017-06-19 14:36 ` Wolfram Sang
2017-06-19 16:34   ` Peter Rosin
2017-06-19 19:30     ` Peter Rosin
2017-06-28 22:20       ` David Thomson
2017-08-18  8:04         ` Peter Rosin
2017-07-31 13:38       ` Wolfram Sang
2017-07-31 14:02         ` Peter Rosin
2017-07-31 14:11           ` Wolfram Sang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).