Skip to content

buffer: do not call memcpy() with a NULL source for an empty append - #824

Open
1820893135-pixel wants to merge 1 commit into
vmg:masterfrom
1820893135-pixel:fix/bufput-zero-length
Open

1820893135-pixel wants to merge 1 commit into
vmg:masterfrom
1820893135-pixel:fix/bufput-zero-length

Conversation

@1820893135-pixel

Copy link
Copy Markdown

Fixes #822.

Root cause

rndr_tablerow() calls bufput(ob, text->data, text->size) for an empty cell,
which passes data == NULL and len == 0. bufput() then calls
memcpy(dst, NULL, 0); the source of memcpy() is declared nonnull, so this
is undefined behavior even though no bytes move:

buffer.c:169:32: runtime error: null pointer passed as argument 2, which is declared to never be null

With -fno-sanitize-recover=all, the one-byte document containing a single
pipe character aborts.

Fix

Return early when len == 0, before the grow and the copy.

Verification

Build (no Ruby needed):

D=ext/redcarpet
clang -g -O1 -D_GNU_SOURCE -std=gnu11 -fsanitize=address,undefined \
  -fno-sanitize-recover=all -I$D driver.c \
  $D/markdown.c $D/html.c $D/html_smartypants.c $D/autolink.c \
  $D/buffer.c $D/stack.c $D/houdini_href_e.c $D/houdini_html_e.c -o repro

with the driver.c from the report.

input bytes before after
a single pipe character 1 exit 1, UBSan buffer.c:169 exit 0

No behaviour change: rendered 71 documents (every
test/MarkdownTest_1.0*/Tests/*.text plus 30 autolink/table/blockquote cases)
with the pristine and the patched build (plain -O2); HTML output, stderr and
exit status are byte-identical.

An empty table cell reaches rndr_tablerow() with text->data == NULL and
text->size == 0, and bufput() then calls memcpy(dst, NULL, 0). The source
of memcpy() is declared nonnull, so that is undefined behavior even
though no bytes move; UBSan reports it, and a trapping build aborts on a
one-byte "|" document.

Return early when len == 0, before the copy and the grow.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]bufput() calls memcpy() with a NULL source for a zero-length append (empty table cell / blockquote) (CWE-476)

1 participant