Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid setting LIMIT_HEAP incorrectly since d90fb23 (included in PCRE2 10.41) #184

Merged
merged 1 commit into from
Jan 17, 2023

Conversation

carenas
Copy link
Contributor

@carenas carenas commented Dec 30, 2022

Avoid the unsigned integer wrap around (triggered in most matches) and use instead an uint32_t variable to hold the heap_limit (in KiB); the following example from pcre2test built with clang's -fsanitize=unsigned-integer-overflow) :

PCRE2 version 10.42 2022-12-11
  re> /a/
data> a
src/pcre2_match.c:6819:42: runtime error: unsigned integer overflow: 20000000 * 1024 cannot be represented in type 'unsigned int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/pcre2_match.c:6819:42 in 
 0: a

Fixes: d90fb23 (Refactor match_data() to always use the heap instead of having an initial frames vector on the stack..., 2022-07-27

@@ -858,7 +858,7 @@ doing traditional NFA matching (pcre2_match() and friends). */

typedef struct match_block {
pcre2_memctl memctl; /* For general use */
PCRE2_SIZE heap_limit; /* As it says */
uint32_t heap_limit; /* As it says */
Copy link
Collaborator

Choose a reason for hiding this comment

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

PCRE2_SIZE is 64 bit long on 64 bit systems, isn't it?

Copy link
Contributor Author

@carenas carenas Dec 30, 2022

Choose a reason for hiding this comment

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

correct, but the heap_limit value can only be lower than UINT32_MAX even if it can represent memory sizes larger than 4GB in 64-bit systems because it uses KB for units.

the main point of this change (other than making it consistent with the other references and saving a little bit of memory) is to try to get the compiler to help us in the future to detect places where similar truncations could be introduced.

@carenas carenas force-pushed the heaplimit2 branch 4 times, most recently from 1274198 to 636f05e Compare January 1, 2023 05:22
@carenas carenas marked this pull request as ready for review January 1, 2023 05:33
@carenas carenas changed the title avoid LIMIT_HEAP truncation since d90fb23 (included in PCRE2 10.41) avoid setting LIMIT_HEAP incorrectly since d90fb23 (included in PCRE2 10.41) Jan 10, 2023
If a LIMIT_HEAP value once converted to bytes is larger than UINT_MAX
would result in a bogus setting that could trigger a matching failure
as shown by the following:

  PCRE2 version 10.42 2022-12-11
    re> /(*LIMIT_HEAP=4194304)a/
  data> a
  Failed: error -63: heap limit exceeded

Remove the multiplication and instead keep track of the maximum heap
allowed in KB as was done originally.

Aditionally, add a check to avoid overflowing a PCRE2_SIZE while
doubling the heap used and that could result in a crash (only on
systems with a 32-bit PCRE2_SIZE and using non standard settings).

Unlike the original, this code avoids rounding the heapframes_size
to the frame_size at the allocation time, which simplifies the logic
and wasn't really needed.

Fixes: d90fb23 (Refactor match_data() to always use the heap instead
       of having an initial frames vector on the stack..., 2022-07-27)
Closes: PCRE2Project#183
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.

3 participants