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

Fix a debug assertion in externref garbage collections #3734

Merged
merged 4 commits into from
Jan 28, 2022

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Jan 27, 2022

See commit messages for details.

// 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
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
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
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?

crates/runtime/src/libcalls.rs Outdated Show resolved Hide resolved
@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

Subscribe to Label Action

cc @fitzgen

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
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