Skip to content

Fix a debug assertion in externref garbage collections#3734

Merged
fitzgen merged 4 commits into
bytecodealliance:mainfrom
fitzgen:externref-debug-assertion-fix
Jan 28, 2022
Merged

Fix a debug assertion in externref garbage collections#3734
fitzgen merged 4 commits into
bytecodealliance:mainfrom
fitzgen:externref-debug-assertion-fix

Conversation

@fitzgen
Copy link
Copy Markdown
Member

@fitzgen fitzgen commented Jan 27, 2022

See commit messages for details.

@fitzgen fitzgen requested a review from alexcrichton January 27, 2022 22:14
// table. So we need to ensure that this `externref` is in the table
// *before* we GC, even though `insert_with_gc` will ensure that it is in
// the table *after* the GC.
activations_table.insert_without_gc(externref.clone());
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.

This can end up doing a double-insertion between this and insert_with_gc below, and it might be good to avoid that? This method is only called when the table is full so insert_without_gc is already guaranteed to go straight to insertion in the slow path, so should a specialized method of the table be added for basically this use case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It won't insert into the bump chunk, so I don't think there is anything to worry about here. We just do one more hash lookup than is strictly necessary, but that is fine as this is a slow path anyways.

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.

That's true, yeah. Could you update the comment here to indicate that this is doing some extra work but it's the slow path so it should be ok?

Comment thread crates/runtime/src/libcalls.rs Outdated
@github-actions github-actions Bot added fuzzing Issues related to our fuzzing infrastructure wasmtime:ref-types Issues related to reference types and GC in Wasmtime labels Jan 27, 2022
When we GC, we assert the invariant that all `externref`s we find on the stack
have a corresponding entry in the `VMExternRefActivationsTable`. However, we
also might be in code that is in the process of fixing up this invariant and
adding an entry to the table, but the table's bump chunk is full, and so we do a
GC and then add the entry into the table. This will ultimately maintain our
desired invariant, but there is a moment in time when we are doing the GC where
the invariant is relaxed which is okay because the reference will be in the
table before we return to Wasm or do anything else. This isn't a possible UAF,
in other words. To make it so that the assertion won't trip, we explicitly
insert the reference into the table *before* we GC, so that the invariant is not
relaxed across a possibly-GCing operation (even though it would be safe in this
particular case).
@fitzgen fitzgen force-pushed the externref-debug-assertion-fix branch from 3fcfe12 to ac10725 Compare January 27, 2022 22:46
@github-actions
Copy link
Copy Markdown

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "fuzzing", "wasmtime:ref-types"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: fuzzing, wasmtime:ref-types

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

This will make it generate `table.set`s that come from `global.get`s and
`global.get`s that come from `table.set`s. Ultimately, it should give us much
more fuzzing coverage of `externref` globals, their barriers, and passing
`externref`s into and out of Wasm to get or set globals.
@fitzgen fitzgen force-pushed the externref-debug-assertion-fix branch from ac10725 to f292ff5 Compare January 28, 2022 00:53
// table. So we need to ensure that this `externref` is in the table
// *before* we GC, even though `insert_with_gc` will ensure that it is in
// the table *after* the GC.
activations_table.insert_without_gc(externref.clone());
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.

That's true, yeah. Could you update the comment here to indicate that this is doing some extra work but it's the slow path so it should be ok?

@fitzgen fitzgen merged commit 34537a3 into bytecodealliance:main Jan 28, 2022
@fitzgen fitzgen deleted the externref-debug-assertion-fix branch January 28, 2022 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fuzzing Issues related to our fuzzing infrastructure wasmtime:ref-types Issues related to reference types and GC in Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants