8000 Storage Permissions: Implement to match TRD by bradjc · Pull Request #4031 · tock/tock · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Storage Permissions: Implement to match TRD #4031

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 20 commits into from
Aug 2, 2024
Merged

Storage Permissions: Implement to match TRD #4031

merged 20 commits into from
Aug 2, 2024

Conversation

bradjc
Copy link
Contributor
@bradjc bradjc commented Jun 17, 2024

Pull Request Overview

This pull request adds an implementation to match the storage permissions TRD.

The core is the StoragePermissions enum:

pub enum StoragePermissionsPrivate {
    SelfOnly(core::num::NonZeroU32),
    FixedSize(FixedSizePermissions),
    Listed(ListedPermissions),
    Kernel,
    Null,
}

Policies then create a storage permissions variant based on how they want to assign applications storage permissions.

To merge the general storage permissions framework with the storage permissions TBF header, the write_id field is just used as a boolean: if the field is 0 the app has no write permissions, otherwise it does.

I also added some components to help with instantiating storage permissions policies.

Testing Strategy

This pull request was tested by...

TODO or Help Wanted

Need to figure out how this works with the HOTP tutorial. Non credentialed apps don't have storage permissions anymore.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

@bradjc bradjc force-pushed the trd-storage-impl branch from f457e5c to 86473d2 Compare June 17, 2024 14:29
@bradjc bradjc force-pushed the trd-storage-impl branch from 86473d2 to f71bab9 Compare June 19, 2024 19:18
@bradjc bradjc added the blocked Waiting on something, like a different PR or a dependency. label Jun 20, 2024
@bradjc
Copy link
Contributor Author
bradjc commented Jun 20, 2024

Thinking about this more, we should wait until after TockWorld (specifically the tutorial).

@bradjc bradjc force-pushed the trd-storage-impl branch from f71bab9 to 48e7cca Compare July 2, 2024 21:00
Needs a wrapper struct to enforce capabilities in the constructor.
@bradjc bradjc removed the blocked Waiting on something, like a different PR or a dependency. label Jul 3, 2024
@bradjc
Copy link
Contributor Author
bradjc commented Jul 3, 2024

Ok I've rebased this and updated capabilities for the constructor. This is ready to go again.

Copy link
Member
@lschuermann lschuermann left a comment

Choose a reason for hiding this comment

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

This certainly took me a while to grok and I'll do another pass in a bit, but it looks good and close to what's in the TRD generally. Two comments above.

Comment on lines 1301 to 1305
///
/// The `storage_permissions_policy` is optional because any app without a
/// fixed `ShortId` cannot have storage permissions, so in cases where an
/// AppID assigner is not used it doesn't make sense to have a storage
/// permissions policy.
Copy link
Member

Choose a reason for hiding this comment

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

Don't we have the null-policy for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is an option. However, we would still need a &'static ProcessStandardStoragePermissionsPolicy which is, I think, a fair bit of confusing overhead for something that doesn't do anything.

Copy link
Member
@lschuermann lschuermann Jul 19, 2024

Choose a reason for hiding this comment

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

Rust allows us to create &'static references to zero-sized types out of thin air: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2b0c391057f50adfb07c62608ff1ef0f (actually, not just ZST but any constant, they get promoted to a static implicitly)

Alternatively, as it's slightly weird to return references from a constructor, we can also make the constructor const and then store the result in a static (which, as it's zero-sized, will not have any runtime overhead): https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9c1f4334f81afdbd6a43d39055de7f70
In particular, this doesn't seem too bad of an option as the null policy doesn't require a capability to construct it.

I don't like that we're using an Option here, as that's one additional branch point for something that we already have semantically encapsulated with the null policy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok! Implementing the null permissions for () worked and the Option<Policy> is gone.

Comment on lines 1705 to 1710
if let Some(storage_perm_policy) = storage_permissions_policy {
process.storage_permissions = storage_perm_policy.get_permissions(process);
} else {
process.storage_permissions = StoragePermissions::new_null();
}

Copy link
Member

Choose a reason for hiding this comment

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

I don't know whether I like this pattern where we're assigning storage permissions in the Process "constructor", and passing the partially constructed process reference into this method here. I'm wondering whether it's not better to assign the storage_permissions field after process construction, and calling this method in the loader instead?

In my opinion, given the storage permissions policy is generic and receives a &ProcessStandard reference, it should be able to expect that reference to be fully constructed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The problem is that ProcessStandard::create() has this signature:

    pub(crate) unsafe fn create<'a>(
        kernel: &'static Kernel,
        chip: &'static C,
        pb: ProcessBinary,
        remaining_memory: &'a mut [u8],
        fault_policy: &'static dyn ProcessFaultPolicy,
        storage_permissions_policy: Option<&'static dyn ProcessStandardStoragePermissionsPolicy<C>>,
        app_id: ShortId,
        index: usize,
    ) -> Result<(Option<&'static dyn Process>, &'a mut [u8]), (ProcessLoadError, &'a mut [u8])>

It returns &Process so the caller cannot set .storage_permissions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not in love with how this is structured in general, but this approach does balance tock use cases with rust limitations in a perhaps reasonable way.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, agreed. I really don't like how the process constructor works here, but this is sound reasoning.

Tangentially, do you know why we're not returning an owned ProcessStandard here that we then move into a static container and take a &'static dyn Process reference to? As stated above, it's kind of weird for a constructor to return a reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rust is hard and we're just doing our best to make the kernel compile.

lschuermann
lschuermann previously approved these changes Jul 19, 2024
Copy link
Member
@lschuermann lschuermann 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 to me generally. If I'm not mistaken it slightly diverges from the TRD where technically necessary. Are there plans to update the TRD language to align it with this implementation?

@lschuermann
Copy link
Member

(I'd appreciate if others could take a look though, as I'm no expert on anything AppID)

bradjc added 2 commits July 23, 2024 14:54
This allows boards that do not use storage permissions to default to
null storage permissions.
@bradjc
Copy link
Contributor Author
bradjc commented Jul 23, 2024

I updated the TRD to hopefully fix all of the impl changes between the original document and this implementation.

@bradjc
Copy link
Contributor Author
bradjc commented Jul 31, 2024

Any other comments?

@lschuermann lschuermann added the last-call Final review period for a pull request. label Aug 2, 2024
@alevy alevy added this pull request to the merge queue Aug 2, 2024
Merged via the queue into master with commit dac9579 Aug 2, 2024
18 checks passed
@alevy alevy deleted the trd-storage-impl branch August 2, 2024 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component kernel last-call Final review period for a pull request.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0