]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA/core: Clear out the udata before error unwind
authorJason Gunthorpe <jgg@mellanox.com>
Tue, 21 May 2019 17:55:22 +0000 (17:55 +0000)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 27 May 2019 17:35:26 +0000 (14:35 -0300)
The core code should not pass a udata to the driver destroy function that
contains the input from the create command. Otherwise the driver will
attempt to interpret the create udata as destroy udata, and at least in
the case of EFA, will leak resources.

Zero this stuff out before invoking destroy.

Reported-by: Leon Romanovsky <leonro@mellanox.com>
Fixes: c4367a26357b ("IB: Pass uverbs_attr_bundle down ib_x destroy path")
Reviewed-by: Gal Pressman <galpress@amazon.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/rdma_core.h
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_std_types_mr.c

index 5445323629b5b5f73bfdfc1b3b94de6f27a1e44a..e63fbda25e1dca17b39075dec54a8fb3699ad601 100644 (file)
@@ -110,6 +110,8 @@ int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);
 void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile);
 void release_ufile_idr_uobject(struct ib_uverbs_file *ufile);
 
+struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs);
+
 /*
  * This is the runtime description of the uverbs API, used by the syscall
  * machinery to validate and dispatch calls.
index 5a3a1780ceea4d47efcdcc022b0f72fd1e194e8b..a9b32ebb9beb77288153ea70905e93e1d8e63fe5 100644 (file)
@@ -174,6 +174,17 @@ static int uverbs_request_finish(struct uverbs_req_iter *iter)
        return 0;
 }
 
+/*
+ * When calling a destroy function during an error unwind we need to pass in
+ * the udata that is sanitized of all user arguments. Ie from the driver
+ * perspective it looks like no udata was passed.
+ */
+struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs)
+{
+       attrs->driver_udata = (struct ib_udata){};
+       return &attrs->driver_udata;
+}
+
 static struct ib_uverbs_completion_event_file *
 _ib_uverbs_lookup_comp_file(s32 fd, struct uverbs_attr_bundle *attrs)
 {
@@ -441,7 +452,7 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
        return uobj_alloc_commit(uobj, attrs);
 
 err_copy:
-       ib_dealloc_pd_user(pd, &attrs->driver_udata);
+       ib_dealloc_pd_user(pd, uverbs_get_cleared_udata(attrs));
        pd = NULL;
 err_alloc:
        kfree(pd);
@@ -644,7 +655,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
        }
 
 err_dealloc_xrcd:
-       ib_dealloc_xrcd(xrcd, &attrs->driver_udata);
+       ib_dealloc_xrcd(xrcd, uverbs_get_cleared_udata(attrs));
 
 err:
        uobj_alloc_abort(&obj->uobject, attrs);
@@ -767,7 +778,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
        return uobj_alloc_commit(uobj, attrs);
 
 err_copy:
-       ib_dereg_mr_user(mr, &attrs->driver_udata);
+       ib_dereg_mr_user(mr, uverbs_get_cleared_udata(attrs));
 
 err_put:
        uobj_put_obj_read(pd);
@@ -2964,7 +2975,7 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
        return uobj_alloc_commit(&obj->uevent.uobject, attrs);
 
 err_copy:
-       ib_destroy_wq(wq, &attrs->driver_udata);
+       ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs));
 err_put_cq:
        uobj_put_obj_read(cq);
 err_put_pd:
@@ -3464,7 +3475,7 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
        return uobj_alloc_commit(&obj->uevent.uobject, attrs);
 
 err_copy:
-       ib_destroy_srq_user(srq, &attrs->driver_udata);
+       ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));
 
 err_free:
        kfree(srq);
index 610d3b9f7654d81b891d2f87f867588b48a8b9b4..997f7a3a558af96c839ca3b74aacc9767bd5fcf8 100644 (file)
@@ -148,7 +148,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(
        return 0;
 
 err_dereg:
-       ib_dereg_mr_user(mr, &attrs->driver_udata);
+       ib_dereg_mr_user(mr, uverbs_get_cleared_udata(attrs));
 
        return ret;
 }