drm/msm: Handle possible overflow in rsp len calculation
If rsp_off, rsp_mem_sz, and len are all zero we could end getting past
the size checks, but msm_context_rsp_noshadow() would still return NULL.
But we should never end up with len==0. Fix rsp length calcs to use the
overflow handling helpers, and add an assert.
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/795>
diff --git a/src/drm/msm/msm_renderer.c b/src/drm/msm/msm_renderer.c
index ce072c3..31e7e7c 100644
--- a/src/drm/msm/msm_renderer.c
+++ b/src/drm/msm/msm_renderer.c
@@ -597,6 +597,8 @@
struct msm_ccmd_rsp *rsp = msm_context_rsp_noshadow(mctx, hdr);
+ assert(len >= sizeof(*rsp));
+
/* With newer host and older guest, we could end up wanting a larger rsp struct
* than guest expects, so allocate a shadow buffer in this case rather than
* having to deal with this in all the different ccmd handlers. This is similar
@@ -625,7 +627,7 @@
{
const struct msm_ccmd_ioctl_simple_req *req = to_msm_ccmd_ioctl_simple_req(hdr);
unsigned payload_len = _IOC_SIZE(req->cmd);
- unsigned req_len = sizeof(*req) + payload_len;
+ unsigned req_len = size_add(sizeof(*req), payload_len);
if (hdr->len != req_len) {
drm_log("%u != %u", hdr->len, req_len);
@@ -654,7 +656,7 @@
unsigned rsp_len = sizeof(*rsp);
if (req->cmd & IOC_OUT)
- rsp_len += payload_len;
+ rsp_len = size_add(rsp_len, payload_len);
rsp = msm_context_rsp(mctx, hdr, rsp_len);
@@ -952,7 +954,7 @@
const struct msm_ccmd_submitqueue_query_req *req =
to_msm_ccmd_submitqueue_query_req(hdr);
struct msm_ccmd_submitqueue_query_rsp *rsp =
- msm_context_rsp(mctx, hdr, sizeof(*rsp) + req->len);
+ msm_context_rsp(mctx, hdr, size_add(sizeof(*rsp), req->len));
if (!rsp)
return -ENOMEM;