Skip to content

pcre2_compile: tighten calculation of re_blocksize - #928

Draft
carenas wants to merge 1 commit into
PCRE2Project:mainfrom
carenas:fuzz32
Draft

pcre2_compile: tighten calculation of re_blocksize#928
carenas wants to merge 1 commit into
PCRE2Project:mainfrom
carenas:fuzz32

Conversation

@carenas

@carenas carenas commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Fixes: #918

@carenas
carenas force-pushed the fuzz32 branch 2 times, most recently from 1b5a9ac to 8d0e4d8 Compare August 3, 2026 07:23
Comment thread src/pcre2_compile.c

PCRE2_SIZE length = 1; /* Allow for final END opcode */
PCRE2_SIZE usedlength; /* Actual length used */
INT64_OR_DOUBLE usedlength; /* Actual length used */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not use double. Just throw an error if the number is too big.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all purposes (specially since the codebase is C99 and most CPUs are 64bit) this is equivalent to int64_t which is of course what we need to check for integer overflows, specially when size_t is 32bit

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually planning to get rid of INT64_OR_DOUBLE. It's only really used in one place, and it isn't actually required there, so ideally it would just disappear.

to avoid integer overflows (specially in 32-bit), use a 64-bit
integer (or equivalent) to add all sections.
Comment thread src/pcre2_compile.c

re_blocksize =
CU2BYTES((PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);
usedlength = CU2BYTES((size_t)cb.names_found * cb.name_entry_size);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about checking the error with: if (CU2BYTES(cb.names_found) > ~(PCRE2_SIZE)0 / CU2BYTES(name_entry_size))

@carenas carenas Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that would be imposible, since both of those are uint16_t, and AFAIK name_entry_size can't be over 128, but agree that the way the checking is done is convoluted and seem to leave gaps.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The arguments are converted to size_t, I don't understand what is impossible.

@NWilson

NWilson commented Aug 9, 2026

Copy link
Copy Markdown
Member

@carenas, would you mind if I had a go at this issue too? I'm digging deeper, and want to clean up and fix quite a few unchecked additions in the same area.

I don't want to ignore your work here, but I would prefer to make a less targeted (broader) fix.

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.

Heap-buffer-overflow WRITE in pcre2_compile_32 (OSS-Fuzz #488713937)

3 participants