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

Add ACLs to contexts to control read-access to objects. #940

Closed
wants to merge 5 commits into from
Closed

Conversation

graydon
Copy link
Contributor

@graydon graydon commented Jul 11, 2023

Another attempt at solving the problem of object access control (an alternative to #930).

This adds 3 separate but related mechanisms to object access control:

  1. Every context (i.e. call-stack frame) gains an ACL which is a bitset indicating which objects in the host object pool the frame can access. When an object is passed from frame A to frame B (during a call) or from B to A (during a return) its corresponding access bit is set in the receiving frame -- the idea being that if you pass someone an object, you intend for them to be able to read it!
  2. The set of objects in the host is split in two separate vectors: one behaving as before, and a new one called "system objects". Object references now come in two flavors depending on their low bit: 1 means system objects and 0 means user objects. The VM marshalling path is modified to check that system object handles are never returned to users (by accident) and if a user tries to forge one it won't work anyway (unless they can figure out a way to feed it into code running in system mode, which should not exist).
  3. The host gains a new boolean flag indicating whether it's running in "system mode", which grants two privileges: access to system objects, and ignoring the context's ACL when looking at non-system objects. Only the auth and event subsystems run in system mode -- there are explicit short-lived transitions into it in a few places, easy to grep for.

The first mechanism (ACLs) broadly isolates objects belonging to each contract from one another. The second mechanism (system objects) lets two subsystems of the host -- auth and events -- freely allocate "their own" objects without perturbing object numbers seen by users and without worrying if they can be seen from the current context. The final mechanism (system mode) allows those subsystems to access system objects from any context, as well as access user objects (eg. for recording objects into the event buffer or authentication trees).

When the auth system calls contracts back for custom auth logic, it transitions back from system to user, and copies the objects of interest from the system table to the object table. Not ideal, but it works.

This is not 100% perfect isolation: there is still a covert channel observable in the allocation of objects. Namely if contract A calls contract B, after B returns A can tell how many objects B allocated by looking at the next available object number. This might be enough to leak information about behaviour B wanted to keep secret. I have an idea of how to close this channel also (changing the system/user split to a global/local split and replacing the ACL with a per-contract indirection table) but that'll take a bit more time. This at least "works" and closes the most egregious channel.

(There are no tests yet, I'm still trying to figure out if this is even the right / final approach to settle on)

@graydon graydon force-pushed the acls branch 4 times, most recently from 06714f6 to 3ff0742 Compare July 12, 2023 23:58
@graydon graydon marked this pull request as ready for review July 13, 2023 00:02
@graydon graydon requested review from sisuresh and a team as code owners July 13, 2023 00:02
@graydon
Copy link
Contributor Author

graydon commented Jul 14, 2023

closing in favor of #947

@graydon graydon closed this Jul 14, 2023
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.

1 participant