RDMA/core: Clear out the udata before error unwind
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: c4367a2635
("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>
This commit is contained in:
parent
619122be3d
commit
6875cb175c
|
@ -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.
|
||||
|
|
|
@ -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 @@ err_copy:
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue