Commit 73984137 authored by Dan Carpenter's avatar Dan Carpenter Committed by Linus Torvalds

rapidio: dereferencing an error pointer

Original patch: https://lkml.org/lkml/2016/8/4/32

If riocm_ch_alloc() fails then we end up dereferencing the error
pointer.

The problem is that we're not unwinding in the reverse order from how we
allocate things so it gets confusing.  I've changed this around so now
"ch" is NULL when we are done with it after we call riocm_put_channel().
That way we can check if it's NULL and avoid calling riocm_put_channel()
on it twice.

I renamed err_nodev to err_put_new_ch so that it better reflects what
the goto does.

Then because we had flipping things around, it means we don't neeed to
initialize the pointers to NULL and we can remove an if statement and
pull things in an indent level.

Link: http://lkml.kernel.org/r/20160805152406.20713-1-alexandre.bounine@idt.comSigned-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarAlexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Cc: Barry Wood <barry.wood@idt.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a0cba217
...@@ -1080,8 +1080,8 @@ static int riocm_send_ack(struct rio_channel *ch) ...@@ -1080,8 +1080,8 @@ static int riocm_send_ack(struct rio_channel *ch)
static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id, static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
long timeout) long timeout)
{ {
struct rio_channel *ch = NULL; struct rio_channel *ch;
struct rio_channel *new_ch = NULL; struct rio_channel *new_ch;
struct conn_req *req; struct conn_req *req;
struct cm_peer *peer; struct cm_peer *peer;
int found = 0; int found = 0;
...@@ -1155,6 +1155,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id, ...@@ -1155,6 +1155,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
spin_unlock_bh(&ch->lock); spin_unlock_bh(&ch->lock);
riocm_put_channel(ch); riocm_put_channel(ch);
ch = NULL;
kfree(req); kfree(req);
down_read(&rdev_sem); down_read(&rdev_sem);
...@@ -1172,7 +1173,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id, ...@@ -1172,7 +1173,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
if (!found) { if (!found) {
/* If peer device object not found, simply ignore the request */ /* If peer device object not found, simply ignore the request */
err = -ENODEV; err = -ENODEV;
goto err_nodev; goto err_put_new_ch;
} }
new_ch->rdev = peer->rdev; new_ch->rdev = peer->rdev;
...@@ -1184,15 +1185,16 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id, ...@@ -1184,15 +1185,16 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
*new_ch_id = new_ch->id; *new_ch_id = new_ch->id;
return new_ch; return new_ch;
err_put:
riocm_put_channel(ch); err_put_new_ch:
err_nodev:
if (new_ch) {
spin_lock_bh(&idr_lock); spin_lock_bh(&idr_lock);
idr_remove(&ch_idr, new_ch->id); idr_remove(&ch_idr, new_ch->id);
spin_unlock_bh(&idr_lock); spin_unlock_bh(&idr_lock);
riocm_put_channel(new_ch); riocm_put_channel(new_ch);
}
err_put:
if (ch)
riocm_put_channel(ch);
*new_ch_id = 0; *new_ch_id = 0;
return ERR_PTR(err); return ERR_PTR(err);
} }
......
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