This is an automated email from the ASF dual-hosted git repository.
chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new 552bfd6e Fix SOFA PBRPC parser not limiting metadata size (#3449)
552bfd6e is described below
commit 552bfd6e25b373f16fd0775d9de1ffcd8272b250
Author: Weibing Wang <[email protected]>
AuthorDate: Sun Aug 16 01:08:59 2026 +0800
Fix SOFA PBRPC parser not limiting metadata size (#3449)
ParseSofaMessage only checked body_size against max_body_size, while
meta_size and the total frame size were left unbounded. A frame with a
large meta_size and zero body_size passed the body_size check and made
the connection keep buffering far beyond the configured limit before the
invalid metadata was rejected. Bound meta_size by max_body_size as well,
consistent with other protocols such as baidu_std and hulu_pbrpc.
Add unit tests covering oversized body and oversized metadata.
---
src/brpc/policy/sofa_pbrpc_protocol.cpp | 9 ++++---
test/brpc_sofa_pbrpc_protocol_unittest.cpp | 42 ++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/src/brpc/policy/sofa_pbrpc_protocol.cpp
b/src/brpc/policy/sofa_pbrpc_protocol.cpp
index 01b21851..328ae4aa 100644
--- a/src/brpc/policy/sofa_pbrpc_protocol.cpp
+++ b/src/brpc/policy/sofa_pbrpc_protocol.cpp
@@ -189,11 +189,12 @@ ParseResult ParseSofaMessage(butil::IOBuf* source,
Socket* socket,
<< " + body_size=" << body_size;
return MakeParseError(PARSE_ERROR_TRY_OTHERS);
}
- if (body_size > FLAGS_max_body_size) {
- // We need this log to report the body_size to give users some clues
+ if (body_size > FLAGS_max_body_size ||
+ meta_size > FLAGS_max_body_size) {
+ // We need this log to report the size to give users some clues
// which is not printed in InputMessenger.
- LOG(ERROR) << "body_size=" << body_size << " from "
- << socket->remote_side() << " is too large";
+ LOG(ERROR) << "body_size=" << body_size << " meta_size=" << meta_size
+ << " from " << socket->remote_side() << " is too large";
return MakeParseError(PARSE_ERROR_TOO_BIG_DATA);
} else if (source->length() < sizeof(header_buf) + msg_size) {
return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA);
diff --git a/test/brpc_sofa_pbrpc_protocol_unittest.cpp
b/test/brpc_sofa_pbrpc_protocol_unittest.cpp
index 4cf91b4f..3996de0e 100644
--- a/test/brpc_sofa_pbrpc_protocol_unittest.cpp
+++ b/test/brpc_sofa_pbrpc_protocol_unittest.cpp
@@ -214,6 +214,26 @@ protected:
MyAuthenticator _auth;
};
+// Build a SOFA header without a real SocketMessage. Fields are stored in host
+// byte order (see PackSofaHeader), each 64-bit field is stored as low 32-bit
+// word followed by high 32-bit word.
+static void AppendSofaTestHeader(butil::IOBuf* buf, uint32_t meta_size,
+ uint64_t body_size, uint64_t msg_size) {
+ char header[24];
+ memcpy(header, "SOFA", 4);
+ const uint32_t meta = meta_size;
+ const uint32_t body_words[2] = {
+ static_cast<uint32_t>(body_size & 0xFFFFFFFFULL),
+ static_cast<uint32_t>(body_size >> 32)};
+ const uint32_t msg_words[2] = {
+ static_cast<uint32_t>(msg_size & 0xFFFFFFFFULL),
+ static_cast<uint32_t>(msg_size >> 32)};
+ memcpy(header + 4, &meta, sizeof(meta));
+ memcpy(header + 8, body_words, sizeof(body_words));
+ memcpy(header + 16, msg_words, sizeof(msg_words));
+ buf->append(header, sizeof(header));
+}
+
TEST_F(SofaTest, process_request_failed_socket) {
brpc::policy::SofaRpcMeta meta;
meta.set_type(brpc::policy::SofaRpcMeta::REQUEST);
@@ -344,4 +364,26 @@ TEST_F(SofaTest, sofa_compress) {
TestSofaCompress(brpc::COMPRESS_TYPE_GZIP);
TestSofaCompress(brpc::COMPRESS_TYPE_ZLIB);
}
+
+TEST_F(SofaTest, reject_oversized_body) {
+ GFLAGS_NAMESPACE::FlagSaver flag_saver;
+ brpc::FLAGS_max_body_size = 1024;
+ const uint64_t body_size = 8 * 1024 * 1024;
+ butil::IOBuf buf;
+ AppendSofaTestHeader(&buf, 0, body_size, body_size);
+ brpc::ParseResult pr =
+ brpc::policy::ParseSofaMessage(&buf, _socket.get(), false, NULL);
+ ASSERT_EQ(brpc::PARSE_ERROR_TOO_BIG_DATA, pr.error());
+}
+
+TEST_F(SofaTest, reject_oversized_meta) {
+ GFLAGS_NAMESPACE::FlagSaver flag_saver;
+ brpc::FLAGS_max_body_size = 1024;
+ const uint32_t meta_size = 8 * 1024 * 1024;
+ butil::IOBuf buf;
+ AppendSofaTestHeader(&buf, meta_size, 0, meta_size);
+ brpc::ParseResult pr =
+ brpc::policy::ParseSofaMessage(&buf, _socket.get(), false, NULL);
+ ASSERT_EQ(brpc::PARSE_ERROR_TOO_BIG_DATA, pr.error());
+}
} //namespace
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]