Commit 931a2505 authored by Andreas Schultz's avatar Andreas Schultz Committed by Greg Kroah-Hartman

[PATCH] I2C: fix unsafe usage of list_for_each in i2c-core

i2c-core.c contains 2 loops that iterate over the list of the clients attached
to an adapter and detaches them. Detaching the clients will actually remove
them from the list the loop is iterating over. Therefore the
list_for_each_safe() method has to be used.
parent 37fd245e
...@@ -124,7 +124,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) ...@@ -124,7 +124,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
int i2c_del_adapter(struct i2c_adapter *adap) int i2c_del_adapter(struct i2c_adapter *adap)
{ {
struct list_head *item; struct list_head *item, *_n;
struct i2c_driver *driver; struct i2c_driver *driver;
struct i2c_client *client; struct i2c_client *client;
int res = 0; int res = 0;
...@@ -144,7 +144,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) ...@@ -144,7 +144,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
/* detach any active clients. This must be done first, because /* detach any active clients. This must be done first, because
* it can fail; in which case we give upp. */ * it can fail; in which case we give upp. */
list_for_each(item,&adap->clients) { list_for_each_safe(item, _n, &adap->clients) {
client = list_entry(item, struct i2c_client, list); client = list_entry(item, struct i2c_client, list);
/* detaching devices is unconditional of the set notify /* detaching devices is unconditional of the set notify
...@@ -215,8 +215,7 @@ int i2c_add_driver(struct i2c_driver *driver) ...@@ -215,8 +215,7 @@ int i2c_add_driver(struct i2c_driver *driver)
int i2c_del_driver(struct i2c_driver *driver) int i2c_del_driver(struct i2c_driver *driver)
{ {
struct list_head *item1; struct list_head *item1, *item2, *_n;
struct list_head *item2;
struct i2c_client *client; struct i2c_client *client;
struct i2c_adapter *adap; struct i2c_adapter *adap;
...@@ -245,7 +244,7 @@ int i2c_del_driver(struct i2c_driver *driver) ...@@ -245,7 +244,7 @@ int i2c_del_driver(struct i2c_driver *driver)
goto out_unlock; goto out_unlock;
} }
} else { } else {
list_for_each(item2,&adap->clients) { list_for_each_safe(item2, _n, &adap->clients) {
client = list_entry(item2, struct i2c_client, list); client = list_entry(item2, struct i2c_client, list);
if (client->driver != driver) if (client->driver != driver)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment