diff options
author | Yann Droneaud <ydroneaud@opteya.com> | 2014-03-11 02:06:27 +0400 |
---|---|---|
committer | Jiri Slaby <jslaby@suse.cz> | 2014-05-15 11:55:11 +0400 |
commit | f6a6a04cde84e4345f4118583aadfc2d7eb320ea (patch) | |
tree | ef094d9c287ec8ce6587a22ffbc99f6bfbcf0672 /drivers/infiniband/hw/nes | |
parent | 452e5d491ce7cd59fdf791f25a259406770a3b21 (diff) | |
download | linux-f6a6a04cde84e4345f4118583aadfc2d7eb320ea.tar.xz |
IB/nes: Return an error on ib_copy_from_udata() failure instead of NULL
commit 9d194d1025f463392feafa26ff8c2d8247f71be1 upstream.
In case of error while accessing to userspace memory, function
nes_create_qp() returns NULL instead of an error code wrapped through
ERR_PTR(). But NULL is not expected by ib_uverbs_create_qp(), as it
check for error with IS_ERR().
As page 0 is likely not mapped, it is going to trigger an Oops when
the kernel will try to dereference NULL pointer to access to struct
ib_qp's fields.
In some rare cases, page 0 could be mapped by userspace, which could
turn this bug to a vulnerability that could be exploited: the function
pointers in struct ib_device will be under userspace total control.
This was caught when using spatch (aka. coccinelle)
to rewrite calls to ib_copy_{from,to}_udata().
Link: https://www.gitorious.org/opteya/ib-hw-nes-create-qp-null
Link: https://www.gitorious.org/opteya/coccib/source/75ebf2c1033c64c1d81df13e4ae44ee99c989eba:ib_copy_udata.cocci
Link: http://marc.info/?i=cover.1394485254.git.ydroneaud@opteya.com
Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 5b53ca5a2284..09999cdec3b1 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1186,7 +1186,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); kfree(nesqp->allocated_buffer); nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n"); - return NULL; + return ERR_PTR(-EFAULT); } if (req.user_wqe_buffers) { virt_wqs = 1; |