Commit 79c3e848 authored by Nuno Sá's avatar Nuno Sá Committed by Jonathan Cameron

iio: inkern: only release the device node when done with it

'of_node_put()' can potentially release the memory pointed to by
'iiospec.np' which would leave us with an invalid pointer (and we would
still pass it in 'of_xlate()'). Note that it is not guaranteed for the
of_node lifespan to be attached to the device (to which is attached)
lifespan so that there is (even though very unlikely) the possibility
for the node to be freed while the device is still around. Thus, as there
are indeed some of_xlate users which do access the node, a race is indeed
possible.

As such, we can only release the node after we are done with it.

Fixes: 17d82b47 ("iio: Add OF support")
Signed-off-by: default avatarNuno Sá <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20220715122903.332535-2-nuno.sa@analog.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 15b2ac67
...@@ -165,9 +165,10 @@ static int __of_iio_channel_get(struct iio_channel *channel, ...@@ -165,9 +165,10 @@ static int __of_iio_channel_get(struct iio_channel *channel,
idev = bus_find_device(&iio_bus_type, NULL, iiospec.np, idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
iio_dev_node_match); iio_dev_node_match);
of_node_put(iiospec.np); if (idev == NULL) {
if (idev == NULL) of_node_put(iiospec.np);
return -EPROBE_DEFER; return -EPROBE_DEFER;
}
indio_dev = dev_to_iio_dev(idev); indio_dev = dev_to_iio_dev(idev);
channel->indio_dev = indio_dev; channel->indio_dev = indio_dev;
...@@ -175,6 +176,7 @@ static int __of_iio_channel_get(struct iio_channel *channel, ...@@ -175,6 +176,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
index = indio_dev->info->of_xlate(indio_dev, &iiospec); index = indio_dev->info->of_xlate(indio_dev, &iiospec);
else else
index = __of_iio_simple_xlate(indio_dev, &iiospec); index = __of_iio_simple_xlate(indio_dev, &iiospec);
of_node_put(iiospec.np);
if (index < 0) if (index < 0)
goto err_put; goto err_put;
channel->channel = &indio_dev->channels[index]; channel->channel = &indio_dev->channels[index];
......
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