diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2015-05-22 16:21:35 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-31 10:05:26 +0900 |
commit | 7e0b1b60cb0d7d3ae4c22a891e11ceccca17afee (patch) | |
tree | a5db0b058b364b4146923ebcff7c1839059b20d0 | |
parent | 613462e1e4d2ea64a29a06fccd3055328354bf3a (diff) | |
download | op-kernel-dev-7e0b1b60cb0d7d3ae4c22a891e11ceccca17afee.zip op-kernel-dev-7e0b1b60cb0d7d3ae4c22a891e11ceccca17afee.tar.gz |
staging: comedi: 8255: fix I/O region leak on failure
The Comedi "8255" driver does not clean up properly on failure. It can
leave requested I/O port regions unreleased. Specifically, the Comedi
"attach" handler (`dev_8255_attach()`) requests a specified I/O port
region before calling `subdev_8255_init()` to set up the subdevice. If
that fails, the "attach" handler returns an error and the Comedi core
will call the "detach" handler (`dev_8255_detach()`) to clean up. The
"detach" handler is responsible for releasing the I/O port regions
successfully requested by the "attach" handler. Unfortunately, it is
unable to obtain the base address of the region if the call to
`subdev_8255_init()` failed.
Fix the I/O region leak by releasing the region in the "attach" handler
directly if the call to `subdev_8255_init()` fails.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/drivers/8255.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index ba89321..0fdf834 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -306,8 +306,15 @@ static int dev_8255_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } else { ret = subdev_8255_init(dev, s, NULL, iobase); - if (ret) + if (ret) { + /* + * Release the I/O port region here, as the + * "detach" handler cannot find it. + */ + release_region(iobase, I8255_SIZE); + s->type = COMEDI_SUBD_UNUSED; return ret; + } } } |