From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964949AbcFMGyG (ORCPT ); Mon, 13 Jun 2016 02:54:06 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:20553 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964818AbcFMGyE (ORCPT ); Mon, 13 Jun 2016 02:54:04 -0400 Date: Mon, 13 Jun 2016 09:53:41 +0300 From: Dan Carpenter To: Moni Shoua Cc: Doug Ledford , Sean Hefty , Hal Rosenstock , linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org Subject: [patch] IB/rxe: fix error code in rxe_srq_from_init() Message-ID: <20160613065341.GA5993@mwanda> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.6.0 (2016-04-01) X-Source-IP: aserv0021.oracle.com [141.146.126.233] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If copy_to_user() fails then it returns the number of bytes not copied. It would be between 1-4 here. Later the callers dereference it leading to an Oops. It was sort of hard to fix this without making the code confusing so I did a little cleanup. Fixes: 443c15d23220 ('IB/rxe: Shared Receive Queue (SRQ) manipulation functions') Signed-off-by: Dan Carpenter diff --git a/drivers/infiniband/hw/rxe/rxe_srq.c b/drivers/infiniband/hw/rxe/rxe_srq.c index 22c57d1..2a6e3cd 100644 --- a/drivers/infiniband/hw/rxe/rxe_srq.c +++ b/drivers/infiniband/hw/rxe/rxe_srq.c @@ -121,8 +121,7 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq, srq_wqe_size); if (!q) { pr_warn("unable to allocate queue for srq\n"); - err = -ENOMEM; - goto err1; + return -ENOMEM; } srq->rq.queue = q; @@ -130,15 +129,14 @@ int rxe_srq_from_init(struct rxe_dev *rxe, struct rxe_srq *srq, err = do_mmap_info(rxe, udata, false, context, q->buf, q->buf_size, &q->ip); if (err) - goto err1; + return err; - if (udata && udata->outlen >= sizeof(struct mminfo) + sizeof(u32)) - return copy_to_user(udata->outbuf + sizeof(struct mminfo), - &srq->srq_num, sizeof(u32)); - else - return 0; -err1: - return err; + if (udata && udata->outlen >= sizeof(struct mminfo) + sizeof(u32)) { + if (copy_to_user(udata->outbuf + sizeof(struct mminfo), + &srq->srq_num, sizeof(u32))) + return -EFAULT; + } + return 0; } int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq,