Skip to content

[TransferEngine] Guard MC_TCP_SLICE_SIZE parsing against std::stoull throwing - #2641

Merged
alogfans merged 2 commits into
kvcache-ai:mainfrom
he-yufeng:fix/tcp-slice-size-env-guard
Jun 28, 2026
Merged

alogfans merged 2 commits into
kvcache-ai:mainfrom
he-yufeng:fix/tcp-slice-size-env-guard

Conversation

@he-yufeng

@he-yufeng he-yufeng commented Jun 26, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

getChunkSize() in tcp_transport.cpp reads the MC_TCP_SLICE_SIZE env var and parses it with std::stoull:

static size_t getChunkSize() {
    static const size_t val = [] {
        const char* env = std::getenv("MC_TCP_SLICE_SIZE");
        if (env) {
            size_t v = std::stoull(env);   // throws on bad input
            if (v > 0) return v;
        }
        return size_t(65536);  // 64KB default
    }();
    return val;
}

The lambda only handles the success path (a positive value; otherwise it falls back to the 64KB default). But a value that std::stoull cannot parse makes it throw:

  • non-numeric string (e.g. a typo like 64K/true) -> std::invalid_argument
  • empty string (export MC_TCP_SLICE_SIZE=, where getenv returns a non-null empty string) -> std::invalid_argument
  • out-of-range number -> std::out_of_range

The parse runs inside the static-local initializer, and neither getChunkSize() nor its callers (the TcpTransport read/write paths at the std::min(getChunkSize(), ...) call sites) catch the exception. So a misconfigured env var aborts the first TCP transfer instead of warning and using the default, which is what the existing if (v > 0) branch already intends for bad input.

Fix

Wrap the parse in try/catch and route both the throwing case and a non-positive value through a warning-and-default path, so any invalid MC_TCP_SLICE_SIZE value degrades gracefully.

This mirrors the env-var parsing that already exists in this codebase:

Verification

13 lines, single file. I did not build locally (the transfer engine needs an RDMA/CUDA toolchain I don't have set up); the change is verified by the C++ standard semantics of std::stoull (throws std::invalid_argument / std::out_of_range on the inputs above) and by matching the established sibling guards listed above, and relies on the existing build/CI jobs to compile-check it. The default-path behavior (64KB) is unchanged for valid and absent values.

…throwing

getChunkSize() reads the MC_TCP_SLICE_SIZE env var and parses it with
std::stoull, but only handles the case where stoull succeeds and returns a
positive value (otherwise it falls back to the 64KB default). A value that
std::stoull cannot parse - a non-numeric string, an empty string, or an
out-of-range number - makes std::stoull throw std::invalid_argument /
std::out_of_range. The parse runs inside the static-local initializer, and
neither getChunkSize() nor the transfer paths that first call it (TcpTransport
read/write) catch the exception, so a typo in the env var aborts the transfer
instead of warning and using the default.

Wrap the parse in try/catch and route both the throwing case and a
non-positive value through the same warning-and-default path, mirroring the
existing MC_MS_AUTO_DISC guard (kvcache-ai#2629) and the env parsing in config.cpp
(MC_PKEY_INDEX / MC_IB_TC / MC_IB_SL), so any invalid MC_TCP_SLICE_SIZE value
degrades gracefully.

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request wraps the parsing of the MC_TCP_SLICE_SIZE environment variable in a try-catch block to prevent exceptions from propagating and aborting the transfer. The reviewer identified an issue where std::stoull can parse negative inputs (such as "-1") into extremely large unsigned values, which would bypass the v > 0 check and potentially cause out-of-memory errors. The reviewer suggested using std::stoll to safely parse and validate the input instead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +45 to +47
try {
size_t v = std::stoull(env);
if (v > 0) return v;

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.

medium

Using std::stoull to parse the environment variable can lead to unexpected behavior if the input is negative (e.g., "-1"). Under the hood, std::stoull (via std::strtoull) allows a leading minus sign and negates the resulting unsigned value, converting "-1" into 18446744073709551615 (ULLONG_MAX). This huge value passes the v > 0 check and is returned as the chunk size, which can cause extremely large memory allocations and potential out-of-memory crashes later in the transport code.

To prevent this, you can parse the value using std::stoll (which returns a signed long long). This way, negative values are correctly parsed as negative numbers, fail the v > 0 check, and safely fall back to the default value.

Suggested change
try {
size_t v = std::stoull(env);
if (v > 0) return v;
try {
long long v = std::stoll(env);
if (v > 0) return static_cast<size_t>(v);

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 0% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...gine/src/transport/tcp_transport/tcp_transport.cpp 0.00% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@alogfans alogfans left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@alogfans
alogfans merged commit e98e90f into kvcache-ai:main Jun 28, 2026
23 checks passed
ZhijunLStudio pushed a commit to ZhijunLStudio/Mooncake that referenced this pull request Jul 2, 2026
…throwing (kvcache-ai#2641)

* [TransferEngine] Guard MC_TCP_SLICE_SIZE parsing against std::stoull throwing

getChunkSize() reads the MC_TCP_SLICE_SIZE env var and parses it with
std::stoull, but only handles the case where stoull succeeds and returns a
positive value (otherwise it falls back to the 64KB default). A value that
std::stoull cannot parse - a non-numeric string, an empty string, or an
out-of-range number - makes std::stoull throw std::invalid_argument /
std::out_of_range. The parse runs inside the static-local initializer, and
neither getChunkSize() nor the transfer paths that first call it (TcpTransport
read/write) catch the exception, so a typo in the env var aborts the transfer
instead of warning and using the default.

Wrap the parse in try/catch and route both the throwing case and a
non-positive value through the same warning-and-default path, mirroring the
existing MC_MS_AUTO_DISC guard (kvcache-ai#2629) and the env parsing in config.cpp
(MC_PKEY_INDEX / MC_IB_TC / MC_IB_SL), so any invalid MC_TCP_SLICE_SIZE value
degrades gracefully.

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>

* clang-format the new MC_TCP_SLICE_SIZE warning logs

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>

---------

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants