Fix TLS module build with OpenSSL 4#4043
Conversation
📝 WalkthroughWalkthroughTwo functions in ChangesOpenSSL 4.0 API compatibility in
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
fef8590 to
a0b6352
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/tls.c`:
- Around line 1313-1320: The code at lines 1313-1320 copies raw ASN1_STRING
bytes without checking for embedded NUL characters. Add a validation check after
retrieving the raw pointer and length (from ASN1_STRING_get0_data and
ASN1_STRING_length) to scan through the raw buffer and reject if any NUL byte is
found within the raw_len bytes. Return 0 immediately if an embedded NUL is
detected, before proceeding with the memcpy operation. This prevents certificate
names like "admin\0evil" from being truncated to "admin" when later used with
strlen() in authentication decisions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #4043 +/- ##
============================================
- Coverage 76.75% 76.73% -0.02%
============================================
Files 162 162
Lines 81021 81021
============================================
- Hits 62185 62173 -12
- Misses 18836 18848 +12
🚀 New features to boost your workflow:
|
a0b6352 to
1abc0e3
Compare
Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com>
1abc0e3 to
3561b45
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/tls.c (1)
1313-1320: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winOpenSSL 4.0+ path diverges from the legacy
X509_NAME_get_text_by_NIDsemantics it replaces, affecting the auth lookup.The legacy call (kept in the
#elsebranch) retrieves the bytes encoded as UTF-8 from the first matching entry, and if the buffer is not large enough, or if the UTF-8 encoding would contain a NUL byte, no data is written and the call returns failure. The new branch copiesASN1_STRING_get0_dataverbatim, which deviates in three ways, all of which feedACLGetUserByName(field_value, strlen(field_value))at Line 1401:
- Encoding mismatch: raw bytes are not UTF-8-converted. Per OpenSSL docs, copying verbatim can be highly confusing if the target is a multicharacter string type like a BMPString or a UTF8String — a BMPString CN (UTF-16BE) yields wrong content (and interior NULs).
- Embedded-NUL rejection still missing: despite being marked addressed previously, the current code has no
memchrcheck, soadmin\0eviltruncates toadminunderstrlen().- Silent truncation vs. failure: on overflow this writes a truncated value and returns success, whereas the legacy API returns failure; a truncated CN could match a different ACL user.
Using
ASN1_STRING_to_UTF8restores legacy behavior and resolves all three.🛡️ Proposed fix using
ASN1_STRING_to_UTF8- const unsigned char *raw = ASN1_STRING_get0_data(data); - int raw_len = ASN1_STRING_length(data); - if (!raw || raw_len <= 0 || outlen == 0) return 0; - - size_t copy_len = (size_t)raw_len < outlen ? (size_t)raw_len : outlen - 1; - memcpy(out, raw, copy_len); - out[copy_len] = '\0'; - return copy_len > 0; + /* Convert to UTF-8 to match the legacy X509_NAME_get_text_by_NID() output. */ + unsigned char *utf8 = NULL; + int utf8_len = ASN1_STRING_to_UTF8(&utf8, data); + if (utf8_len <= 0 || utf8 == NULL) { + OPENSSL_free(utf8); + return 0; + } + /* Reject embedded NUL and treat buffer overflow as failure (no truncation), + * mirroring the legacy API and protecting the downstream strlen()-based lookup. */ + if (outlen == 0 || (size_t)utf8_len >= outlen || + memchr(utf8, '\0', (size_t)utf8_len) != NULL) { + OPENSSL_free(utf8); + return 0; + } + memcpy(out, utf8, (size_t)utf8_len); + out[utf8_len] = '\0'; + OPENSSL_free(utf8); + return 1;Please confirm
ASN1_STRING_to_UTF8is available across the OpenSSL versions this branch targets (4.0+).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/tls.c` around lines 1313 - 1320, The code block extracting and copying the ASN1 string data (using ASN1_STRING_get0_data followed by memcpy) does not properly handle UTF-8 encoding conversion, embedded NUL byte validation, or overflow semantics required by the legacy X509_NAME_get_text_by_NID API it replaces. Replace the ASN1_STRING_get0_data and memcpy approach with ASN1_STRING_to_UTF8, which automatically handles UTF-8 conversion for all string types, includes embedded-NUL detection, and returns proper failure semantics on buffer overflow. Verify that ASN1_STRING_to_UTF8 is available in all OpenSSL versions this code targets (4.0+).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/tls.c`:
- Around line 1313-1320: The code block extracting and copying the ASN1 string
data (using ASN1_STRING_get0_data followed by memcpy) does not properly handle
UTF-8 encoding conversion, embedded NUL byte validation, or overflow semantics
required by the legacy X509_NAME_get_text_by_NID API it replaces. Replace the
ASN1_STRING_get0_data and memcpy approach with ASN1_STRING_to_UTF8, which
automatically handles UTF-8 conversion for all string types, includes
embedded-NUL detection, and returns proper failure semantics on buffer overflow.
Verify that ASN1_STRING_to_UTF8 is available in all OpenSSL versions this code
targets (4.0+).
|
Wow! Missed this. Let me close this PR |
Failure link: https://github.com/valkey-io/valkey/actions/runs/27993975032/job/82852152994#step:8:746
Fedora Rawhide now treats the deprecated X509 APIs as build errors, so the TLS code uses the OpenSSL 4-= safe APIs where needed while keeping the existing paths for older OpenSSL versions.
The CI with
run-extra-testslabel will be blocked till this issue is resolved.test-fedorarawhide-tls-modulepassedtest-fedorarawhide-tls-module-no-tlspassed