reject negative attachment_size in baidu_std request/response parsing by sahvx655-wq · Pull Request #3604 · apache/brpc · GitHub
Skip to content

reject negative attachment_size in baidu_std request/response parsing - #3604

Open
sahvx655-wq wants to merge 1 commit into
apache:masterfrom
sahvx655-wq:baidu-attachment-size-negative
Open

sahvx655-wq wants to merge 1 commit into
apache:masterfrom
sahvx655-wq:baidu-attachment-size-negative

Conversation

@sahvx655-wq

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: resolve

Problem Summary:

RpcMeta.attachment_size is optional int32 (baidu_rpc_meta.proto) and is copied from the peer. In ProcessRpcRequest and ProcessRpcResponse (src/brpc/policy/baidu_rpc_protocol.cpp) it is validated only against an upper bound (req_size < attachment_size, attachment_size > res_size). A negative value passes both guards and reaches

int body_without_attachment_size = res_size - meta.attachment_size();

With attachment_size = INT32_MIN and a small body (an empty body is a valid baidu_std message), res_size - attachment_size overflows signed int, which is undefined behavior; the UBSan job in CI aborts on it. For other negative values the subtraction yields a size larger than the payload, so the body/attachment split silently desyncs.

Reproduced the arithmetic with the real types under -fsanitize=undefined: attachment_size=INT32_MIN, req_size=0 gives runtime error: signed integer overflow: 0 - -2147483648 cannot be represented in type 'int' and aborts; with the negative value rejected it returns cleanly.

Siblings checked: hulu uses cutn(user_message_size) (bounded by IOBuf, no subtraction) and sofa has no attachment, so neither shares the pattern. Both affected sites are in this file.

What is changed and the side effects?

Changed:

  • Reject attachment_size < 0 at the request and response guards, so the later int subtraction always has a non-negative operand.

Side effects:

  • Performance effects: none.

  • Breaking backward compatibility: none. A valid attachment_size is a byte count and is always >= 0; only malformed negative values are now rejected with the existing SetFailed path.


Check List:

  • Changes are compilable; the diff only tightens an existing condition.
  • Verified with a UBSan reproducer of the exact subtraction (before: abort on INT32_MIN; after: clean reject). No committed unit test since this parser path needs a full server/client round-trip to exercise and I could not build the suite in my environment; happy to add one if you prefer.
  • Follows the Code of Conduct.

This fix was found and prepared with AI assistance and reviewed by me before submitting.

attachment_size is a peer-controlled int32 but both guards only check an upper bound, so a negative value reaches res_size - attachment_size (int) and overflows for INT32_MIN. Reject attachment_size < 0 at both sites.
@wwbmmm
wwbmmm requested a balanced review from Copilot October 21, 2026 02:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

2 open issues
What changed in this PR

Tightens baidu_std request/response parsing validation to reject negative RpcMeta.attachment_size, preventing signed overflow/UB and payload/body desynchronization.

Changes:

  • Add attachment_size < 0 guards in both request and response parsing paths.
  • Update failure messages to reflect invalid attachment_size values.
File Description
src/​brpc/​policy/​baidu_rpc_protocol.cpp Adds lower-bound validation for attachment_size in request/response parsing and updates related SetFailed messages.

Review effort: Lite

Comment on lines +712 to +715
if (meta.attachment_size() < 0 ||
req_size < meta.attachment_size()) {
cntl->SetFailed(EREQUEST,
"attachment_size=%d is larger than request_size=%d",
"Invalid attachment_size=%d (request_size=%d)",
Comment on lines +1022 to 1026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants