From 3a311f8866d7b9e4987335c74b5032dc5c787b21 Mon Sep 17 00:00:00 2001 From: chinaxing Date: Mon, 14 Aug 2023 09:12:27 +0000 Subject: [PATCH] [CP] [4.1] fix tx-route state serialize size overflow --- src/observer/mysql/obmp_utils.cpp | 17 ++++++++++++++--- src/storage/tx/ob_tx_free_route.cpp | 14 ++++++-------- unittest/storage/tx/it/test_tx_free_route.cpp | 3 +-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/observer/mysql/obmp_utils.cpp b/src/observer/mysql/obmp_utils.cpp index 23c66a2848..4b673f32ab 100644 --- a/src/observer/mysql/obmp_utils.cpp +++ b/src/observer/mysql/obmp_utils.cpp @@ -279,6 +279,7 @@ int ObMPUtils::append_modfied_sess_info(common::ObIAllocator &allocator, } else if (encoder->is_changed_) { int16_t info_type = (int16_t)i; int32_t info_len = sess_size[i]; + int64_t info_pos = 0; LOG_DEBUG("session-info-encode", K(sess.get_sessid()), K(info_type), K(info_len)); if (info_len < 0) { ret = OB_INVALID_ARGUMENT; @@ -287,10 +288,14 @@ int ObMPUtils::append_modfied_sess_info(common::ObIAllocator &allocator, // invalid info len do nothing and skip it. encoder->is_changed_ = false; } else if (OB_FAIL(ObProtoTransUtil::store_type_and_len(buf, size, pos, info_type, info_len))) { - LOG_WARN("failed to set type and len", K(info_type), K(info_len), K(ret)); - } else if (OB_FAIL(encoder->serialize(sess, buf, size, pos))) { - LOG_WARN("failed to serialize", K(sess), K(ret), K(size), K(pos)); + LOG_WARN("failed to set type and len", K(ret), K(info_type), K(info_len), K(pos)); + } else if (pos + info_len > size) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("buf overflow for info", K(ret), K(buf), K(pos), K(info_type), K(info_len), K(size)); + } else if (OB_FAIL(encoder->serialize(sess, buf + pos, info_len, info_pos))) { + LOG_WARN("failed to serialize", K(sess), K(ret), K(size), K(buf), K(pos), K(info_type), K(info_len), K(info_pos)); } else { + pos += info_len; // reset to not changed encoder->is_changed_ = false; } @@ -335,6 +340,12 @@ int ObMPUtils::append_modfied_sess_info(common::ObIAllocator &allocator, } } } + if (OB_FAIL(ret)) { + // dump info size array + for (int i = 0; i< SESSION_SYNC_MAX_TYPE; i++) { + LOG_INFO("dump sess info size", "type", i, "size", sess_size[i]); + } + } } return ret; diff --git a/src/storage/tx/ob_tx_free_route.cpp b/src/storage/tx/ob_tx_free_route.cpp index ef7307b858..5e7a44852c 100644 --- a/src/storage/tx/ob_tx_free_route.cpp +++ b/src/storage/tx/ob_tx_free_route.cpp @@ -199,14 +199,12 @@ public: int64_t TxStateHeader::encode_length() { - int64_t l = encoded_length_i64(1) - + encoded_length_i64(1) - + encoded_length_i8(1); - if (with_version_()) { - l += encoded_length_i16(100); // length - l += encoded_length_i8(1); // version - l += encoded_length_i32(1); // backend_sess_id - } + int64_t l = encoded_length_i64(1) // tx_id_ + + encoded_length_i64(1) // global_version_ + + encoded_length_i8(1) // flag_ + + encoded_length_i16(100) // length_ + + encoded_length_i8(1) // version_ + + encoded_length_i32(1); // backend_sess_id_ return l; } diff --git a/unittest/storage/tx/it/test_tx_free_route.cpp b/unittest/storage/tx/it/test_tx_free_route.cpp index 747f8fbdd3..836a498c01 100644 --- a/unittest/storage/tx/it/test_tx_free_route.cpp +++ b/unittest/storage/tx/it/test_tx_free_route.cpp @@ -423,8 +423,7 @@ int MockObServer::handle(ObReq &req, ObResp &resp) OB_FAIL(tx_node_.txn_free_route__update_##tn##_state(session_.get_sessid(), tx_desc, free_route_ctx, buf, len, pos))) { \ TRANS_LOG(ERROR, "update txn state fail", K(ret), "type", #T); \ } else if (pos != len) { \ - ret = OB_ERR_UNEXPECTED; \ - TRANS_LOG(ERROR, "oops: pos != len, consume buffer incomplete", K(ret), K(pos), K(len), "state_type", #T); \ + TRANS_LOG(WARN, "[maybe] pos != len, consume buffer incomplete", K(ret), K(pos), K(len), "state_type", #T); \ } \ break; #define TX_STATE_UPDATE_(T, tn) TX_STATE_UPDATE__(T, tn)