Repository navigation
Fix remaining buffer size in vendored storage commands - #13
Conversation
Pass the remaining command buffer capacity to snprintf after advancing the buffer pointer. This keeps storage command formatting compatible with stricter compiler checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 605c1c5d-4b41-4ee4-8db3-a38d2ab61a30
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request. Check if the Files changed in this pull request are included in default exclusions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 605c1c5d-4b41-4ee4-8db3-a38d2ab61a30
|
The two changed Both calls write at The command, prefix and key are copied into
A 386-byte header overflows the 350-byte stack buffer inside the A guard ahead of the first if (strlen(command) + strlen(ptr->prefix_key) + key_length + 1 >= MEMCACHED_DEFAULT_COMMAND_SIZE)
return MEMCACHED_BAD_KEY_PROVIDED;A test that sets a 250-character key under a 127-character prefix covers it. The overflow figures come from the limits in the source. No build has reproduced the crash yet.
|
Reject command, prefix, and key combinations that leave no room in the command buffer before copying them. Cover oversized inputs, the exact capacity boundary, and delete with noreply. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 605c1c5d-4b41-4ee4-8db3-a38d2ab61a30
Summary
Update the two
snprintfcalls in the vendored libmemcached storage-command path to passMEMCACHED_DEFAULT_COMMAND_SIZE - write_length.Both calls write through
buffer_ptrafter it has advanced past the command and key. The size argument must therefore describe the remaining capacity rather than the entire buffer.Add a length guard before the first
memcpyto reject command, prefix, key, and separating-space combinations that fill or exceed the command buffer. Add three regression tests covering oversized prefix/key combinations, the exact buffer-capacity boundary, and delete withnoreply.Why
Builds using
_FORTIFY_SOURCE=3and LTO can abort during ordinary storage operations because the original size argument exceeds the space remaining atbuffer_ptr. Passing the remaining capacity makes the formatting compatible with these compiler checks while preserving the existing command format and final length checks.The pre-copy guard ensures that the command and key data fit before being copied and that the remaining-capacity subtraction cannot wrap around. Prefix and key lengths are otherwise validated independently, which does not guarantee their combination fits the command buffer.
This change covers both the delete-with-
noreplypath and the other non-CAS storage operations. The CAS path already formats from the beginning of the buffer and is unchanged.Validation
git diff --check.MemcachedExperimentalTest#test_touchtest (Memcached::NotFound), matching the earlier PR runs.minitest 5.26.0requires Ruby below 4.0, while head is 4.1.0.dev._FORTIFY_SOURCE=2; it does not exercise the exact level-3-plus-LTO configuration described above.