Skip to content

Commit d0257e0

Browse files
Dan Carpenterrleon
authored andcommitted
RDMA/uverbs: Prevent integer overflow issue
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]>
1 parent eb867d7 commit d0257e0

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;
@@ -2008,11 +2008,13 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs)
20082008
ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd));
20092009
if (ret)
20102010
return ret;
2011-
wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count);
2011+
wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size,
2012+
cmd.wr_count));
20122013
if (IS_ERR(wqes))
20132014
return PTR_ERR(wqes);
2014-
sgls = uverbs_request_next_ptr(
2015-
&iter, cmd.sge_count * sizeof(struct ib_uverbs_sge));
2015+
sgls = uverbs_request_next_ptr(&iter,
2016+
size_mul(cmd.sge_count,
2017+
sizeof(struct ib_uverbs_sge)));
20162018
if (IS_ERR(sgls))
20172019
return PTR_ERR(sgls);
20182020
ret = uverbs_request_finish(&iter);
@@ -2198,11 +2200,11 @@ ib_uverbs_unmarshall_recv(struct uverbs_req_iter *iter, u32 wr_count,
21982200
if (wqe_size < sizeof(struct ib_uverbs_recv_wr))
21992201
return ERR_PTR(-EINVAL);
22002202

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

0 commit comments

Comments
 (0)