Whamcloud - gitweb
LU-12603 ldlm: Check cancel lock count for correctness 08/36108/3
authorOleg Drokin <green@whamcloud.com>
Sat, 17 Aug 2019 05:36:07 +0000 (01:36 -0400)
committerOleg Drokin <green@whamcloud.com>
Thu, 12 Sep 2019 03:52:25 +0000 (03:52 +0000)
Make sure the number of locks we are going to cancel fits into
the supplied buffer first.

Lustre-change: https://review.whamcloud.com/35806
Lustre-commit: 7cc43aef98f6a759cbc5ae572123b44803c0ccd2

Change-Id: I93887133532bf7ee2be27114b1972aa64e06623c
Signed-off-by: Oleg Drokin <green@whamcloud.com>
Reported-by: Alibaba Cloud <yunye.ry@alibaba-inc.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Yunye Ry <yunye.ry@alibaba-inc.com>
Signed-off-by: Minh Diep <mdiep@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/36108
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/ldlm/ldlm_lockd.c

index 3584d66..5280277 100644 (file)
@@ -1600,12 +1600,19 @@ int ldlm_request_cancel(struct ptlrpc_request *req,
        struct ldlm_resource *res, *pres = NULL;
        struct ldlm_lock *lock;
        int i, count, done = 0;
+       unsigned int size;
 
        ENTRY;
 
-        count = dlm_req->lock_count ? dlm_req->lock_count : 1;
-        if (first >= count)
-                RETURN(0);
+       size = req_capsule_get_size(&req->rq_pill, &RMF_DLM_REQ, RCL_CLIENT);
+       if (size <= offsetof(struct ldlm_request, lock_handle) ||
+           (size - offsetof(struct ldlm_request, lock_handle)) /
+            sizeof(struct lustre_handle) < dlm_req->lock_count)
+               RETURN(0);
+
+       count = dlm_req->lock_count ? dlm_req->lock_count : 1;
+       if (first >= count)
+               RETURN(0);
 
        if (count == 1 && dlm_req->lock_handle[0].cookie == 0)
                RETURN(0);
@@ -1689,14 +1696,18 @@ int ldlm_handle_cancel(struct ptlrpc_request *req)
                 RETURN(-EFAULT);
         }
 
-        if (req->rq_export && req->rq_export->exp_nid_stats &&
-            req->rq_export->exp_nid_stats->nid_ldlm_stats)
-                lprocfs_counter_incr(req->rq_export->exp_nid_stats->nid_ldlm_stats,
-                                     LDLM_CANCEL - LDLM_FIRST_OPC);
+       if (req_capsule_get_size(&req->rq_pill, &RMF_DLM_REQ, RCL_CLIENT) <
+           offsetof(struct ldlm_request, lock_handle[1]))
+               RETURN(-EPROTO);
+
+       if (req->rq_export && req->rq_export->exp_nid_stats &&
+           req->rq_export->exp_nid_stats->nid_ldlm_stats)
+               lprocfs_counter_incr(req->rq_export->exp_nid_stats->nid_ldlm_stats,
+                                    LDLM_CANCEL - LDLM_FIRST_OPC);
 
-        rc = req_capsule_server_pack(&req->rq_pill);
-        if (rc)
-                RETURN(rc);
+       rc = req_capsule_server_pack(&req->rq_pill);
+       if (rc)
+               RETURN(rc);
 
        if (!ldlm_request_cancel(req, dlm_req, 0, LATF_STATS))
                req->rq_status = LUSTRE_ESTALE;