Skip to content

match: Properly align heapframes for CHERI/Arm's Morello prototype #72

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

Merged
merged 1 commit into from
Jan 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/pcre2_intmodedep.h
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,17 @@ multiple of PCRE2_SIZE. See various comments above. */
typedef char check_heapframe_size[
((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)];

/* Structure for computing the alignment of heapframe. */

typedef struct heapframe_align {
char unalign; /* Completely unalign the current offset */
heapframe frame; /* Offset is its alignment */
} heapframe_align;

/* This define is the minimum alignment required for a heapframe, in bytes. */

#define HEAPFRAME_ALIGNMENT offsetof(heapframe_align, frame)

/* Structure for passing "static" information around between the functions
doing traditional NFA matching (pcre2_match() and friends). */

Expand Down
14 changes: 10 additions & 4 deletions src/pcre2_match.c
Original file line number Diff line number Diff line change
Expand Up @@ -6781,10 +6781,16 @@ the pattern. It is not used at all if there are no capturing parentheses.

The last of these is changed within the match() function if the frame vector
has to be expanded. We therefore put it into the match block so that it is
correct when calling match() more than once for non-anchored patterns. */
correct when calling match() more than once for non-anchored patterns.

frame_size = offsetof(heapframe, ovector) +
re->top_bracket * 2 * sizeof(PCRE2_SIZE);
We must also pad frame_size for alignment to ensure subsequent frames are as
aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE
array, that does not guarantee it is suitably aligned for pointers, as some
architectures have pointers that are larger than a size_t. */

frame_size = (offsetof(heapframe, ovector) +
re->top_bracket * 2 * sizeof(PCRE2_SIZE) + HEAPFRAME_ALIGNMENT - 1) &
~(HEAPFRAME_ALIGNMENT - 1);

/* Limits set in the pattern override the match context only if they are
smaller. */
Expand Down Expand Up @@ -6828,7 +6834,7 @@ mb->match_frames_top =
to avoid uninitialized memory read errors when it is copied to a new frame. */

memset((char *)(mb->match_frames) + offsetof(heapframe, ovector), 0xff,
re->top_bracket * 2 * sizeof(PCRE2_SIZE));
frame_size - offsetof(heapframe, ovector));

/* Pointers to the individual character tables */

Expand Down