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;