From c2a6f1a2afee6c416a3e7659b863bcc6246761f0 Mon Sep 17 00:00:00 2001 From: Emoly Liu Date: Wed, 27 Nov 2019 22:35:56 +0800 Subject: [PATCH 1/1] LU-12811 ptlrpc: pass buflen to lustre_swab_object_update_*() 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 Change-Id: I229c1946ec3c088c7804762655f143dc419b2ea0 Reviewed-on: https://review.whamcloud.com/36867 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin --- lustre/include/lustre_swab.h | 5 +++-- lustre/ptlrpc/layout.c | 4 ++-- lustre/ptlrpc/pack_generic.c | 43 ++++++++++++++++++++++++++++++++++--------- lustre/target/out_handler.c | 2 +- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lustre/include/lustre_swab.h b/lustre/include/lustre_swab.h index 720f7a2..8a56513 100644 --- a/lustre/include/lustre_swab.h +++ b/lustre/include/lustre_swab.h @@ -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); diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index bc37679e..ad804d8 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -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); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 91639eb..5d53f19 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -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) diff --git a/lustre/target/out_handler.c b/lustre/target/out_handler.c index 2849b7b..e91c338 100644 --- a/lustre/target/out_handler.c +++ b/lustre/target/out_handler.c @@ -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" -- 1.8.3.1