Skip to content

Commit

Permalink
rapidio: dereferencing an error pointer
Browse files Browse the repository at this point in the history
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.com
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alexandre 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Dan Carpenter authored and torvalds committed Aug 10, 2016
1 parent a0cba21 commit 7398413
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions drivers/rapidio/rio_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
long timeout)
{
struct rio_channel *ch = NULL;
struct rio_channel *new_ch = NULL;
struct rio_channel *ch;
struct rio_channel *new_ch;
struct conn_req *req;
struct cm_peer *peer;
int found = 0;
Expand Down Expand Up @@ -1155,6 +1155,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,

spin_unlock_bh(&ch->lock);
riocm_put_channel(ch);
ch = NULL;
kfree(req);

down_read(&rdev_sem);
Expand All @@ -1172,7 +1173,7 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,
if (!found) {
/* If peer device object not found, simply ignore the request */
err = -ENODEV;
goto err_nodev;
goto err_put_new_ch;
}

new_ch->rdev = peer->rdev;
Expand All @@ -1184,15 +1185,16 @@ static struct rio_channel *riocm_ch_accept(u16 ch_id, u16 *new_ch_id,

*new_ch_id = new_ch->id;
return new_ch;

err_put_new_ch:
spin_lock_bh(&idr_lock);
idr_remove(&ch_idr, new_ch->id);
spin_unlock_bh(&idr_lock);
riocm_put_channel(new_ch);

err_put:
riocm_put_channel(ch);
err_nodev:
if (new_ch) {
spin_lock_bh(&idr_lock);
idr_remove(&ch_idr, new_ch->id);
spin_unlock_bh(&idr_lock);
riocm_put_channel(new_ch);
}
if (ch)
riocm_put_channel(ch);
*new_ch_id = 0;
return ERR_PTR(err);
}
Expand Down

0 comments on commit 7398413

Please sign in to comment.