Skip to content

Fix use-after-free in the C API attribute iterator - #339

Open
PGZXB wants to merge 1 commit into
cloudflare:mainfrom
PGZXB:fix-issue-336
Open

PGZXB wants to merge 1 commit into
cloudflare:mainfrom
PGZXB:fix-issue-336

Conversation

@PGZXB

@PGZXB PGZXB commented Sep 25, 2026

Copy link
Copy Markdown

Fixes #336.

lol_html_attributes_iterator_get returned a std::slice::Iter borrowed from the element's attribute Vec. lol_html_element_set_attribute (and lol_html_element_remove_attribute) grow or rebuild that Vec, so the next call to lol_html_attributes_iterator_next walked a stale slice cursor into a buffer that had already been freed, even though the iterator is documented to stay valid for the whole handler.

The iterator now carries the element pointer and a cursor and _next re-reads the element's attributes on each call, so mutating the element between calls no longer invalidates the iteration:

lol_html_attribute_t *attr = lol_html_attributes_iterator_next(iter);   // first attribute
lol_html_element_set_attribute(element, "zzzzzzzzzzzzzzzzzzzz", 20, "1", 1);
attr = lol_html_attributes_iterator_next(iter);                         // next attribute, no UAF

Verified with the reproducer from the issue (<div a="1" b="2" c="3">, advance once, mutate, advance again), built against the C API with AddressSanitizer. Before the change it reports ERROR: AddressSanitizer: heap-use-after-free on the second next; after the change it runs cleanly and prints the next attribute. cargo fmt --check and cargo clippy --manifest-path=c-api/Cargo.toml are clean.

@PGZXB
PGZXB requested review from a team, Noah-Kennedy, jasnell and orium as code owners September 25, 2026 08:25
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.

use-after-free: c-api attribute handles are invalidated by mutating the element

1 participant