Skip to content

Commit

Permalink
IB/core: Encorce MR access rights rules on kernel consumers
Browse files Browse the repository at this point in the history
Enforce the rule that when requesting remote write or atomic permissions, local
write must be indicated as well. See IB spec 11.2.8.2.

Spotted by: Hagay Abramovsky <hagaya@mellanox.com>
Signed-off-by: Eli Cohen <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
  • Loading branch information
Eli Cohen authored and Roland Dreier committed Nov 15, 2013
1 parent 180771a commit 1c636f8
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
10 changes: 3 additions & 7 deletions drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,13 +939,9 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
return -EINVAL;

/*
* Local write permission is required if remote write or
* remote atomic permission is also requested.
*/
if (cmd.access_flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
!(cmd.access_flags & IB_ACCESS_LOCAL_WRITE))
return -EINVAL;
ret = ib_check_mr_access(cmd.access_flags);
if (ret)
return ret;

uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
if (!uobj)
Expand Down
14 changes: 14 additions & 0 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,11 @@ EXPORT_SYMBOL(ib_resize_cq);
struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
{
struct ib_mr *mr;
int err;

err = ib_check_mr_access(mr_access_flags);
if (err)
return ERR_PTR(err);

mr = pd->device->get_dma_mr(pd, mr_access_flags);

Expand All @@ -983,6 +988,11 @@ struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
u64 *iova_start)
{
struct ib_mr *mr;
int err;

err = ib_check_mr_access(mr_access_flags);
if (err)
return ERR_PTR(err);

if (!pd->device->reg_phys_mr)
return ERR_PTR(-ENOSYS);
Expand Down Expand Up @@ -1013,6 +1023,10 @@ int ib_rereg_phys_mr(struct ib_mr *mr,
struct ib_pd *old_pd;
int ret;

ret = ib_check_mr_access(mr_access_flags);
if (ret)
return ret;

if (!mr->device->rereg_phys_mr)
return -ENOSYS;

Expand Down
13 changes: 13 additions & 0 deletions include/rdma/ib_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2386,4 +2386,17 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp,
struct ib_flow_attr *flow_attr, int domain);
int ib_destroy_flow(struct ib_flow *flow_id);

static inline int ib_check_mr_access(int flags)
{
/*
* Local write permission is required if remote write or
* remote atomic permission is also requested.
*/
if (flags & (IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_REMOTE_WRITE) &&
!(flags & IB_ACCESS_LOCAL_WRITE))
return -EINVAL;

return 0;
}

#endif /* IB_VERBS_H */

0 comments on commit 1c636f8

Please sign in to comment.