node: bounds-check and OOM-guard in cmark_set_cstr#609
Open
Alearner12 wants to merge 1 commit into
Open
Conversation
cmark_set_cstr backs every cmark string setter (cmark_node_set_url, _set_title, _set_literal, _set_fence_info, _set_on_enter, _set_on_exit). This change closes two paths to undefined behaviour: 1. The realloc result is not checked. mem->realloc can return NULL via stdlib OOM or a caller-supplied allocator (cmark exposes the allocator through cmark_node_new_with_mem). The next line dereferences it, so failure is UB inside memcpy rather than a defined abort. 2. The bufsize_t cast of strlen silently truncates. bufsize_t is int32_t; for strlen(src) > INT32_MAX the cast wraps and subsequent len + 1 and memcpy operate on a truncated count. Both now abort() with a diagnostic, matching the existing precedent in cmark_strbuf_grow (src/buffer.c). Co-Authored-By: Claude <noreply@anthropic.com>
Member
|
Looks good. @nwellnhof any comments? |
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.
node: bounds-check and OOM-guard in cmark_set_cstr
cmark_set_cstrinsrc/node.cbacks every cmark string setter —cmark_node_set_url,_set_title,_set_literal,_set_fence_info,_set_on_enter,_set_on_exit. It has two paths to undefined behaviour that I think are worth closing.1. The
reallocresult is not checked.mem->realloccan return NULL — either stdlib OOM or, more importantly, a caller-supplied allocator (cmark exposes the allocator throughcmark_node_new_with_mem). The next line dereferences it, so failure is UB insidememcpyrather than a defined abort. Other unreasonable-state paths in cmark — for example thetarget_size > INT32_MAX/2branch incmark_strbuf_grow(src/buffer.c:43-48) — alreadyabort()with a diagnostic. This change keeps that pattern.2. The
bufsize_tcast ofstrlensilently truncates.bufsize_tisint32_t(src/buffer.h:16). Forstrlen(src) > INT32_MAXthe cast wraps; subsequentlen + 1andmemcpy(*dst, src, len + 1)operate on a truncated (or, for some wraparounds, negative) count. The function then returns this incorrect length to the caller, which uses it as a size elsewhere. SameINT32_MAXbound and abort treatment as Defect 1.Verification
Built against current master (
b320f40) with-fsanitize=address,undefined. A small reproducer usingcmark_node_new_with_memto inject a failingrealloc:Before:
After this patch:
api_teston the patched build:556 tests passed, 0 failed, 0 skipped.