Skip to content

Commit b92667f

Browse files
Dan Carpentergregkh
authored andcommitted
RDMA/uverbs: Prevent integer overflow issue
commit d0257e0 upstream. In the expression "cmd.wqe_size * cmd.wr_count", both variables are u32 values that come from the user so the multiplication can lead to integer wrapping. Then we pass the result to uverbs_request_next_ptr() which also could potentially wrap. The "cmd.sge_count * sizeof(struct ib_uverbs_sge)" multiplication can also overflow on 32bit systems although it's fine on 64bit systems. This patch does two things. First, I've re-arranged the condition in uverbs_request_next_ptr() so that the use controlled variable "len" is on one side of the comparison by itself without any math. Then I've modified all the callers to use size_mul() for the multiplications. Fixes: 67cdb40 ("[IB] uverbs: Implement more commands") Cc: [email protected] Signed-off-by: Dan Carpenter <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c9818b6 commit b92667f

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static const void __user *uverbs_request_next_ptr(struct uverbs_req_iter *iter,
161161
{
162162
const void __user *res = iter->cur;
163163

164-
if (iter->cur + len > iter->end)
164+
if (len > iter->end - iter->cur)
165165
return (void __force __user *)ERR_PTR(-ENOSPC);
166166
iter->cur += len;
167167
return res;
@@ -2009,11 +2009,13 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs)
20092009
ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd));
20102010
if (ret)
20112011
return ret;
2012-
wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count);
2012+
wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size,
2013+
cmd.wr_count));
20132014
if (IS_ERR(wqes))
20142015
return PTR_ERR(wqes);
2015-
sgls = uverbs_request_next_ptr(
2016-
&iter, cmd.sge_count * sizeof(struct ib_uverbs_sge));
2016+
sgls = uverbs_request_next_ptr(&iter,
2017+
size_mul(cmd.sge_count,
2018+
sizeof(struct ib_uverbs_sge)));
20172019
if (IS_ERR(sgls))
20182020
return PTR_ERR(sgls);
20192021
ret = uverbs_request_finish(&iter);
@@ -2199,11 +2201,11 @@ ib_uverbs_unmarshall_recv(struct uverbs_req_iter *iter, u32 wr_count,
21992201
if (wqe_size < sizeof(struct ib_uverbs_recv_wr))
22002202
return ERR_PTR(-EINVAL);
22012203

2202-
wqes = uverbs_request_next_ptr(iter, wqe_size * wr_count);
2204+
wqes = uverbs_request_next_ptr(iter, size_mul(wqe_size, wr_count));
22032205
if (IS_ERR(wqes))
22042206
return ERR_CAST(wqes);
2205-
sgls = uverbs_request_next_ptr(
2206-
iter, sge_count * sizeof(struct ib_uverbs_sge));
2207+
sgls = uverbs_request_next_ptr(iter, size_mul(sge_count,
2208+
sizeof(struct ib_uverbs_sge)));
22072209
if (IS_ERR(sgls))
22082210
return ERR_CAST(sgls);
22092211
ret = uverbs_request_finish(iter);

0 commit comments

Comments
 (0)