Skip to content

Check that stack frames are not too large#10085

Merged
xavierleroy merged 2 commits intoocaml:trunkfrom
xavierleroy:stack-frame-too-large
Dec 14, 2020
Merged

Check that stack frames are not too large#10085
xavierleroy merged 2 commits intoocaml:trunkfrom
xavierleroy:stack-frame-too-large

Conversation

@xavierleroy
Copy link
Copy Markdown
Contributor

The frame table uses 16-bit unsigned integers to store the size of a stack frame as well as the number and offsets of roots.

In extreme cases, the sizes and offsets can overflow these 16-bit fields, as reported in #10072.

This PR adds a compile-time error if these 16-bit fields overflow.

The code is engineered so that the 7 asmcomp/$ARCH/emit.mlp files are unmodified. The check is done in asmcomp/emitaux.ml, raising an Emitaux.Error exception, which is caught in asmcomp/asmgen.ml, enriched with a bit of context, and re-raised as an Asmgen.Error exception.

The frame table uses 16-bit unsigned integers to store the size of a
stack frame as well as the number and offsets of roots.

This commit adds a compile-time error if these 16-bit fields overflow.

Closes: ocaml#10072
Copy link
Copy Markdown
Member

@gasche gasche left a comment

Choose a reason for hiding this comment

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

This looks good, with the usual nitpicking comments below.

One thing I found surprising is that efa_16 is now checked (and violating its invariant is a code-production error that we report to users) but efa_8 and efa_32 are not. I reviewed the code in emitaux, and it appears that there is no need for such a dynamic check:

  • use-cases of efa_8 statically assert that the input is within range
    (the key assumption is that Config.max_young_wosize is 2^8 or below, but this is recalled in the code; we must also not combine more than 2^8 allocations, but this is a consequence of allocation having strictly positive sizes and combined allocations being below max_young_wosize).
  • the single use-case of efa_32 appears to respect the condition as well

assert (n >= 0);
if n < 0x1_0000
then a.efa_16 n
else raise (Error(Stack_frame_too_large n))
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.

It is strange that the error precisely mentions stack frames, while this function could be used for other things by emitaux or a specific code emitter. One way to avoid this would be to have a generic Out_of_range exception raised here, and have the user code in emit_frame catch it and raise this contextual exception. (Two reraises for the price of one!)

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.

The efa_16_checked function is local to emit_frame, so we know all the call sites, and they are all about stack frame characteristics (size, number of roots, offsets of roots). I don't think more generality is warranted.

@xavierleroy xavierleroy merged commit baf71d1 into ocaml:trunk Dec 14, 2020
@xavierleroy xavierleroy deleted the stack-frame-too-large branch January 9, 2021 17:12
dbuenzli pushed a commit to dbuenzli/ocaml that referenced this pull request Mar 25, 2021
The frame table uses 16-bit unsigned integers to store the size of a
stack frame as well as the number and offsets of roots.

This commit adds a compile-time error if these 16-bit fields overflow.

Closes: ocaml#10072
edwintorok pushed a commit to edwintorok/ocaml that referenced this pull request Jun 27, 2021
The frame table uses 16-bit unsigned integers to store the size of a
stack frame as well as the number and offsets of roots.

This commit adds a compile-time error if these 16-bit fields overflow.

Closes: ocaml#10072
(cherry picked from commit baf71d1)
stedolan pushed a commit to stedolan/ocaml that referenced this pull request May 24, 2022
The frame table uses 16-bit unsigned integers to store the size of a
stack frame as well as the number and offsets of roots.

This commit adds a compile-time error if these 16-bit fields overflow.

Closes: ocaml#10072

Co-authored-by: Xavier Leroy <xavierleroy@users.noreply.github.com>
stedolan pushed a commit to stedolan/ocaml that referenced this pull request May 24, 2022
fe8a98b flambda-backend: Save Mach as Cfg after Selection (ocaml#624)
2b205d8 flambda-backend: Clean up algorithms (ocaml#611)
524f0b4 flambda-backend: Initial refactoring of To_cmm (ocaml#619)
0bf75de flambda-backend: Refactor and correct the "is pure" and "can raise" (port upstream PR#10354 and PR#10387) (ocaml#555)
d234bfd flambda-backend: Cpp mangling is now a configuration option (ocaml#614)
20fc614 flambda-backend: Check that stack frames are not too large (ocaml#10085) (ocaml#561)
5fc2e95 flambda-backend: Allow CSE of immutable loads across stores (port upstream PR#9562) (ocaml#562)
2a650de flambda-backend: Backport commit fc95347 from trunk (ocaml#584)
31651b8 flambda-backend: Improved ARM64 code generation (port upstream PR#9937) (ocaml#556)
f0b6d68 flambda-backend: Simplify processing and remove dead code (error paths) in asmlink (port upstream PR#9943) (ocaml#557)
90c6746 flambda-backend: Improve code-generation for inlined comparisons (port upstream PR#10228) (ocaml#563)

git-subtree-dir: ocaml
git-subtree-split: fe8a98b
lpw25 pushed a commit to lpw25/ocaml that referenced this pull request Jun 21, 2022
…) (ocaml#561)

The frame table uses 16-bit unsigned integers to store the size of a
stack frame as well as the number and offsets of roots.

This commit adds a compile-time error if these 16-bit fields overflow.

Closes: ocaml#10072

Co-authored-by: Xavier Leroy <xavierleroy@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants