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]

Reply via email to