Repository navigation
Fix IP SAN handling in cert_write and cert_req - #11002
Open
JayOfTheKeyboard wants to merge 2 commits into
Open
JayOfTheKeyboard wants to merge 2 commits into
JayOfTheKeyboard wants to merge 2 commits into
Conversation
mbedtls_x509_crt_parse_cn_inet_pton() requires a 16-byte buffer and writes 16 bytes for an IPv6 address, but both programs passed a 4-byte one. Use a 16-byte buffer and record the length the function returns instead of sizeof(ip), so IPv6 addresses are encoded as 16 bytes. Signed-off-by: Jeremy Levartovsky <[email protected]>
Every IP entry in the san list pointed at the same buffer, and the list is only written once all entries are parsed, so san=IP:1.2.3.4;IP:5.6.7.8 produced two copies of 5.6.7.8. Give each IP entry its own buffer and free it with the rest of the list. Signed-off-by: Jeremy Levartovsky <[email protected]>
This was referenced Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The
cert_writeandcert_reqsample programs mishandleIP:entries in thesanparameter in two ways. This PR fixes both.1. Stack buffer overflow with an IPv6 address
Both programs declare a 4-byte buffer and pass it to
mbedtls_x509_crt_parse_cn_inet_pton():The function's documentation in
include/mbedtls/x509.hsays:A value containing
:is parsed as IPv6 and 16 bytes are written, so 12 bytes land past the end ofip. Reproduce with an ASan build:cert_reqgives the same report against itsipat line 156. Without ASan the program does not crash, and the length is still hard coded to 4. The usage text saysIP:value (Only IPv4 is supported), but nothing enforces that.That note dates from the earlier hand-written IPv4 parser. #7638 replaced it with
mbedtls_x509_crt_parse_cn_inet_pton(), which accepts IPv6, but kept the 4-byte buffer. The SAN writer copiesunstructured_name.lenbytes as given, so a 16-byte address is encoded correctly once the programs pass the right length. This PR makes IPv6 work.2. Several IP entries all get the last address
Every IP entry points at that one shared
ipbuffer, and the SAN list is only written after all entries are parsed. So:With
san=IP:2001:db8::1;IP:10.0.0.1and only the first fix applied, the IPv4 address overwrites the first 4 bytes of the IPv6 one, givingIP Address:A00:1:0:0:0:0:0:1.Fix
Two commits, applied identically to both programs.
mbedtls_x509_crt_parse_cn_inet_pton()returns. Update the usage text toIP:value (IPv4 or IPv6).mbedtls_calloc(), and free it in the existing cleanup loop atexit:, as is already done for DN entries. This removes the stack buffer, and with it a redundant#if defined(MBEDTLS_X509_CRT_PARSE_C)incert_req.c. The whole program already requires that option.Security impact
The overflow is only reachable through the
sancommand-line argument of a sample program, which the person running it controls. The library itself is not affected. Its own caller inx509_crt.cand thex509parsetest suite both pass 16-byte buffers. This matches the earlier "Fix possible NULL dereference issue in X509 cert_write/cert_req program if an entry in the san parameter is not separated by a colon" fixes, which were listed as ordinary bugfixes in 3.6.0.Testing
There is no test harness that runs
cert_writeorcert_req, as #7638 also noted. I tested by hand with an ASan and UBSan build (clang,-fsanitize=address,undefined -fno-sanitize-recover=all,ASAN_OPTIONS=detect_leaks=1). The script runs both programs with five inputs and compares the SAN thatopenssl x509/openssl reqdecodes:IP:1.2.3.4DNS:a;IP:2001:db8::1IP:1.2.3.4;IP:5.6.7.85.6.7.8IP:2001:db8::1;IP:10.0.0.1IP:not-an-ipThat is 6 of 10 checks failing on the parent and 10 of 10 passing with this PR, on
development,mbedtls-4.1andmbedtls-3.6.I also broke each part of the fix and reran the checks:
mbedtls_exit()from insidemain, so LeakSanitizer still sees the local pointer. I kept the free because the buffer is otherwise leaked.framework/scripts/code_style.py(uncrustify 0.75.1),framework/scripts/check_files.pyandframework/scripts/assemble_changelog.pypass. Both programs build with gcc andMBEDTLS_FATAL_WARNINGS=ONon all three branches.Not changed
data_files, which only exercises the parser. I left that for the maintainers to decide.IPorDNentry fails to parse, the list node allocated just before it is still not freed. That was already the case and the program exits right away, so I did not touch it.sanlist. That is unchanged.san=twice replaces the first list without freeing it. That leak was already there. With this PR it also holds the IP buffers of the first list.cert_writeandcert_reqstill duplicate their SAN parsing. Moving it into one shared helper would stop a fix like this one being needed twice, but it is a larger change.PR checklist
cert_writeandcert_req. Tested by hand under ASan as described above.