Whamcloud - gitweb
LU-539 obd_data_connect server side could be corrupted
authorBobi Jam <bobijam@whamcloud.com>
Tue, 26 Jul 2011 17:36:18 +0000 (01:36 +0800)
committerOleg Drokin <green@whamcloud.com>
Mon, 1 Aug 2011 14:50:58 +0000 (10:50 -0400)
In target_handle_connect(), we use assignment to copy client's connect
data to its server counterpart, and we define the pointers pointing to
a big buffer (struct obd_connect_data), while server's reply connect
data could be a smaller buffer (struct obd_connect_data_v1), the
assignment could corrupt the request's obd_connect_data reply buffer.

Change-Id: Ib72776d3dee8a2a836fda5b29ab49c3bbc026cab
Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Reviewed-on: http://review.whamcloud.com/1144
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ldlm/ldlm_lib.c

index f55e5be..9d063d8 100644 (file)
@@ -666,6 +666,7 @@ int target_handle_connect(struct ptlrpc_request *req)
         int rc = 0;
         int mds_conn = 0;
         struct obd_connect_data *data, *tmpdata;
+        int size, tmpsize;
         lnet_nid_t *client_nid = NULL;
         ENTRY;
 
@@ -733,6 +734,8 @@ int target_handle_connect(struct ptlrpc_request *req)
 
         conn = *tmp;
 
+        size = req_capsule_get_size(&req->rq_pill, &RMF_CONNECT_DATA,
+                                    RCL_CLIENT);
         data = req_capsule_client_get(&req->rq_pill, &RMF_CONNECT_DATA);
         if (!data)
                 GOTO(out, rc = -EPROTO);
@@ -926,10 +929,14 @@ dont_check_exports:
         /* Return only the parts of obd_connect_data that we understand, so the
          * client knows that we don't understand the rest. */
         if (data) {
-                 tmpdata = req_capsule_server_get(&req->rq_pill,
-                                                  &RMF_CONNECT_DATA);
-                  //data->ocd_connect_flags &= OBD_CONNECT_SUPPORTED;
-                 *tmpdata = *data;
+                tmpsize = req_capsule_get_size(&req->rq_pill, &RMF_CONNECT_DATA,
+                                               RCL_SERVER);
+                tmpdata = req_capsule_server_get(&req->rq_pill,
+                                                 &RMF_CONNECT_DATA);
+                /* Don't use struct assignment here, because the client reply
+                 * buffer may be smaller/larger than the local struct
+                 * obd_connect_data. */
+                memcpy(tmpdata, data, min(tmpsize, size));
         }
 
         /* If all else goes well, this is our RPC return code. */