Whamcloud - gitweb
LU-12811 ptlrpc: pass buflen to lustre_swab_object_update_*() 67/36867/5
authorEmoly Liu <emoly@whamcloud.com>
Wed, 27 Nov 2019 14:35:56 +0000 (22:35 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 11 Mar 2020 02:10:07 +0000 (02:10 +0000)
Pass the buffer size to the swabbing functions
lustre_swab_object_update_reply() and
lustre_swab_object_update_request() to avoid invalid access,
especially for small buffer.

Signed-off-by: Emoly Liu <emoly@whamcloud.com>
Change-Id: I229c1946ec3c088c7804762655f143dc419b2ea0
Reviewed-on: https://review.whamcloud.com/36867
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_swab.h
lustre/ptlrpc/layout.c
lustre/ptlrpc/pack_generic.c
lustre/target/out_handler.c

index 720f7a2..8a56513 100644 (file)
@@ -114,11 +114,12 @@ void lustre_swab_hsm_user_state(struct hsm_user_state *hus);
 void lustre_swab_hsm_user_item(struct hsm_user_item *hui);
 void lustre_swab_hsm_request(struct hsm_request *hr);
 void lustre_swab_object_update(struct object_update *ou);
-void lustre_swab_object_update_request(struct object_update_request *our);
+int lustre_swab_object_update_request(struct object_update_request *our,
+                                     __u32 len);
 void lustre_swab_out_update_header(struct out_update_header *ouh);
 void lustre_swab_out_update_buffer(struct out_update_buffer *oub);
 void lustre_swab_object_update_result(struct object_update_result *our);
-void lustre_swab_object_update_reply(struct object_update_reply *our);
+int lustre_swab_object_update_reply(struct object_update_reply *our, __u32 len);
 void lustre_swab_swap_layouts(struct mdc_swap_layouts *msl);
 void lustre_swab_close_data(struct close_data *data);
 void lustre_swab_close_data_resync_done(struct close_data_resync_done *resync);
index bc37679..ad804d8 100644 (file)
@@ -1263,12 +1263,12 @@ struct req_msg_field RMF_MDS_HSM_REQUEST =
                    lustre_swab_hsm_request, NULL);
 EXPORT_SYMBOL(RMF_MDS_HSM_REQUEST);
 
-struct req_msg_field RMF_OUT_UPDATE = DEFINE_MSGF("object_update", 0, -1,
+struct req_msg_field RMF_OUT_UPDATE = DEFINE_MSGFL("object_update", 0, -1,
                                lustre_swab_object_update_request, NULL);
 EXPORT_SYMBOL(RMF_OUT_UPDATE);
 
 struct req_msg_field RMF_OUT_UPDATE_REPLY =
-                       DEFINE_MSGF("object_update_reply", 0, -1,
+                       DEFINE_MSGFL("object_update_reply", 0, -1,
                                    lustre_swab_object_update_reply, NULL);
 EXPORT_SYMBOL(RMF_OUT_UPDATE_REPLY);
 
index 91639eb..5d53f19 100644 (file)
@@ -2909,20 +2909,37 @@ void lustre_swab_object_update(struct object_update *ou)
        }
 }
 
-void lustre_swab_object_update_request(struct object_update_request *our)
+int lustre_swab_object_update_request(struct object_update_request *our,
+                                     __u32 len)
 {
-       size_t i;
+       __u32 i, size = 0;
+       struct object_update *ou;
+
        __swab32s(&our->ourq_magic);
        __swab16s(&our->ourq_count);
        __swab16s(&our->ourq_padding);
-       for (i = 0; i < our->ourq_count; i++) {
-               struct object_update *ou;
 
+       /* Don't need to calculate request size if len is 0. */
+       if (len > 0) {
+               size = sizeof(struct object_update_request);
+               for (i = 0; i < our->ourq_count; i++) {
+                       ou = object_update_request_get(our, i, NULL);
+                       if (ou == NULL)
+                               return -EPROTO;
+                       size += sizeof(struct object_update) +
+                               ou->ou_params_count *
+                               sizeof(struct object_update_param);
+               }
+               if (unlikely(size > len))
+                       return -EOVERFLOW;
+       }
+
+       for (i = 0; i < our->ourq_count; i++) {
                ou = object_update_request_get(our, i, NULL);
-               if (ou == NULL)
-                       return;
                lustre_swab_object_update(ou);
        }
+
+       return size;
 }
 
 void lustre_swab_object_update_result(struct object_update_result *our)
@@ -2932,22 +2949,30 @@ void lustre_swab_object_update_result(struct object_update_result *our)
        __swab16s(&our->our_padding);
 }
 
-void lustre_swab_object_update_reply(struct object_update_reply *our)
+int lustre_swab_object_update_reply(struct object_update_reply *our, __u32 len)
 {
-       size_t i;
+       __u32 i, size;
 
        __swab32s(&our->ourp_magic);
        __swab16s(&our->ourp_count);
        __swab16s(&our->ourp_padding);
+
+       size = sizeof(struct object_update_reply) + our->ourp_count *
+              (sizeof(__u16) + sizeof(struct object_update_result));
+       if (unlikely(size > len))
+               return -EOVERFLOW;
+
        for (i = 0; i < our->ourp_count; i++) {
                struct object_update_result *ourp;
 
                __swab16s(&our->ourp_lens[i]);
                ourp = object_update_result_get(our, i, NULL);
                if (ourp == NULL)
-                       return;
+                       return -EPROTO;
                lustre_swab_object_update_result(ourp);
        }
+
+       return size;
 }
 
 void lustre_swab_out_update_header(struct out_update_header *ouh)
index 2849b7b..e91c338 100644 (file)
@@ -1055,7 +1055,7 @@ int out_handle(struct tgt_session_info *tsi)
 
                our = update_bufs[i];
                if (ptlrpc_req_need_swab(pill->rc_req))
-                       lustre_swab_object_update_request(our);
+                       lustre_swab_object_update_request(our, 0);
 
                if (our->ourq_magic != UPDATE_REQUEST_MAGIC) {
                        CERROR("%s: invalid update buffer magic %x"