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

runtime/type-registry: add new type-registry library for the type confusion APIs #493

Merged
merged 4 commits into from
Feb 19, 2025

Conversation

kkysen
Copy link
Contributor

@kkysen kkysen commented Jan 6, 2025

This is written in Rust like memory-map is, so I made the CMakeLists.txt very similar. Since the library may be called concurrently, it uses a hash map which is non-trivial in C, and we already have Rust libraries like memory-map, Rust seemed like a good choice here.

There are a few other things I think we want to do here, such as ensuring a type doesn't change across the duration of the function call (not just the beginning); this would be done with a read lock. Also, we probably want to store the compartment number along with the type ID. But I'll do these in follow-up PRs once we get the initial parts working.

@kkysen kkysen requested review from ayrtonm and fw-immunant January 6, 2025 19:39
Copy link
Contributor

@fw-immunant fw-immunant left a comment

Choose a reason for hiding this comment

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

A couple points.

One is that I don't think there's a reason to have a PtrAddr struct or rust *const () here: usize is guaranteed to be the right size, and we never dereference. Then sorting/etc. behavior for usize does the right thing with no need to impl various traits.

The other is that I don't think we in general want to panic here, because we'll be unwinding through other languages (and we want to stop execution as soon as possible given that we've observed an inconsistency that could indicate memory corruption). Maybe we should abort directly, or choose whether to abort vs. panicking with a #[cfg(test)] or such to allow using the Rust test harness. I'm not sure if panic = abort would work here or be easy to apply.

@fw-immunant
Copy link
Contributor

ensuring a type doesn't change across the duration of the function call (not just the beginning); this would be done with a read lock

Do you mean something like:

  • take lock
  • call wrapped library function
  • drop lock
    ?

I don't think that's reasonable to do in the presence of concurrent calls to the library, because we don't know the user's expectations of the library itself w/r/t locking. It could be that the user requires two calls to enter the library before either will return.

@kkysen
Copy link
Contributor Author

kkysen commented Jan 29, 2025

One is that I don't think there's a reason to have a PtrAddr struct or rust *const () here: usize is guaranteed to be the right size, and we never dereference. Then sorting/etc. behavior for usize does the right thing with no need to impl various traits.

Okay, I can do it this way I think. Strict provenance is also stabilized now, which makes it simpler to do this fully correctly/clearly with usize now.

The other is that I don't think we in general want to panic here, because we'll be unwinding through other languages (and we want to stop execution as soon as possible given that we've observed an inconsistency that could indicate memory corruption). Maybe we should abort directly, or choose whether to abort vs. panicking with a #[cfg(test)] or such to allow using the Rust test harness. I'm not sure if panic = abort would work here or be easy to apply.

What about using extern "C-unwind"? Also, can't we set panic = "abort" in a cdylib?

@kkysen
Copy link
Contributor Author

kkysen commented Jan 29, 2025

I don't think that's reasonable to do in the presence of concurrent calls to the library, because we don't know the user's expectations of the library itself w/r/t locking. It could be that the user requires two calls to enter the library before either will return.

Yeah, you're probably right about this. Let me think about it a bit more, but you're probably right; I didn't think through all the possible cases.

@fw-immunant
Copy link
Contributor

One is that I don't think there's a reason to have a PtrAddr struct or rust *const () here: usize is guaranteed to be the right size, and we never dereference. Then sorting/etc. behavior for usize does the right thing with no need to impl various traits.

Okay, I can do it this way I think. Strict provenance is also stabilized now, which makes it simpler to do this fully correctly/clearly with usize now.

As far as I understand, provenance doesn't come into play here if we never cast back from the pointer/addr to a reference. Will we need to do so later for some reason?

The other is that I don't think we in general want to panic here, because we'll be unwinding through other languages (and we want to stop execution as soon as possible given that we've observed an inconsistency that could indicate memory corruption). Maybe we should abort directly, or choose whether to abort vs. panicking with a #[cfg(test)] or such to allow using the Rust test harness. I'm not sure if panic = abort would work here or be easy to apply.

What about using extern "C-unwind"? Also, can't we set panic = "abort" in a cdylib?

I was concerned that panic = "abort" would interfere with the rust test harness, but I just tested a few cases and it appears that cargo test somehow ignores panic = "abort" in profile.dev/profile.test/profile.release and makes should_panic tests work regardless. We would want panic = "abort" in our Cargo.toml here for integration into the C to avoid continuing execution past the known invalid state.

@kkysen kkysen force-pushed the kkysen/type-registry-library branch from a86cd53 to 1d69f70 Compare January 31, 2025 06:32
@kkysen kkysen force-pushed the kkysen/type-registry-library branch from 1d69f70 to 34a4883 Compare February 18, 2025 05:46
…onfusion APIs

This is written in Rust like `memory-map` is, so I made the `CMakeLists.txt` very similar.
Since the library may be called concurrently, it uses a hash map which is non-trivial in C,
and we already have Rust libraries like `memory-map`, Rust seemed like a good choice here.
@kkysen kkysen force-pushed the kkysen/type-registry-library branch from 34a4883 to bf0d83d Compare February 18, 2025 06:07
@kkysen
Copy link
Contributor Author

kkysen commented Feb 18, 2025

As far as I understand, provenance doesn't come into play here if we never cast back from the pointer/addr to a reference. Will we need to do so later for some reason?

It just makes it clearer the exact provenance semantics of what we're doing, and to not accidentally expose provenance (which we don't ever need to do).

I was concerned that panic = "abort" would interfere with the rust test harness, but I just tested a few cases and it appears that cargo test somehow ignores panic = "abort" in profile.dev/profile.test/profile.release and makes should_panic tests work regardless. We would want panic = "abort" in our Cargo.toml here for integration into the C to avoid continuing execution past the known invalid state.

👍 I also included extern "C-unwind". I'm not sure the exact semantics of that, but I don't think it hurts, and we still have panic = "abort".

@kkysen
Copy link
Contributor Author

kkysen commented Feb 18, 2025

One is that I don't think there's a reason to have a PtrAddr struct or rust *const () here: usize is guaranteed to be the right size, and we never dereference. Then sorting/etc. behavior for usize does the right thing with no need to impl various traits.

I kept the newtype PtrAddr but made it over usize, which simplifies things. I didn't want to have the C signatures use usize when we'll call them with a pointer from C. It'd work, but it makes the provenance implications more confusing.

@kkysen kkysen requested a review from fw-immunant February 18, 2025 06:10
Copy link
Contributor

@fw-immunant fw-immunant left a comment

Choose a reason for hiding this comment

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

LGTM.

@kkysen kkysen merged commit 8037e4a into main Feb 19, 2025
33 of 34 checks passed
@kkysen kkysen deleted the kkysen/type-registry-library branch February 19, 2025 02:30
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.

2 participants