FIDL support for handle type and rights checking

5 views
Skip to first unread message

Benjamin Prosnitz

unread,
Jun 14, 2021, 7:14:23 AM6/14/21
to fidl-dev

tl;dr: it is now possible to specify required rights on handles in FIDL files


Hi Team,


Handle rights can now be specified in FIDL files and be validated (along with object type) in all FIDL bindings. Rights annotations help to improve security by better aligning expectations with reality.


RFC-0028 provides more details on the motivation.


Okay, I’m excited. How can I use it?


Rights can be specified as an optional second parameter on handles:


struct HandleWithRights {

  // The | operator performs a bitwise-or of the rights.

  zx.handle:<CHANNEL, zx.rights.TRANSFER | zx.rights.READ> h;

};


If the rights parameter is omitted, the rights are zx.rights.SAME_RIGHTS.


Client and server ends have object type CHANNEL and rights zx.DEFAULT_CHANNEL_RIGHTS.


Very cool. But, where are all of the rights defined?


Rights are defined as a bits in the zx library in //zircon/vdso/rights.fidl. In addition to the rights bits definition, this file contains constants defining sets of bits, like zx.RIGHTS_BASIC.


That makes sense - could you explain the ‘|’?


| is the bitwise OR operator for FIDL bits. This works on all bits, not just rights.


I’m a details person. Could you explain the object type and rights checks more?


Sure. Identical object type and rights checks happen in the sending and receiving directions.


Suppose a FIDL field has required rights R and a handle h is sent in it:

  • It is an error for h to be missing rights that are present in R. The channel will be closed.

  • If h has more rights than R, its rights are reduced to R through zx_handle_replace.


Additionally, it is an error for a handle to be sent not matching the type specified in the FIDL file, resulting in channel closure.


And this is ready now?! I have many use cases in mind!

Yes, this is ready today. Please consider it for new and existing APIs.


If you have further questions, don’t hesitate to reach out to fidl...@fuchsia.net


Josh Gargus

unread,
Jun 15, 2021, 8:49:46 AM6/15/21
to tq-eng, Benjamin Prosnitz, fidl-dev
Just curious, is there polymorphism in the handle type?  For example, can you pass a channel where the expected type is EVENTPAIR, since the channel can respond to all of the same syscalls as an eventpair (and then some)?  This mostly only makes sense for EVENTPAIR and other peered types, since for EVENT you could just omit the handle type: everything can act like an event.

Also, I might be thinking about this wrong, but it seems slightly burdensome to have to say zx.rights.TRANSFER explicitly.  Isn't it true that this right always needs to be set, otherwise it can't be sent across via a protocol bound to a channel?  I suppose the rights reduction could happen on the receiver side, so the handle is transferred and then made untransferable.  But then that constrains the ability of the server implementation to delegate to a different component.  Constraining the implementation based on the interface definition doesn't seem desirable, in general.  Would it make sense to modify this feature so that zx.rights.TRANSFER is always implicitly assumed?  Or should it just be API Council guidance that all SDK protocols shall explicitly declare this right (that is, if they use the optional second parameter at all)?  Or... ?

I'm not sure what you mean when you say "Client and server ends have object type CHANNEL and rights zx.DEFAULT_CHANNEL_RIGHTS".  Is this a typo?  zx.DEFAULT_CHANNEL_RIGHTS isn't the same as zx.rights.TRANSFER | zx.rights.READ, so I'm not sure what is meant here.

Thanks,
Josh
On Monday, June 14, 2021 at 3:11:03 AM UTC-7 Benjamin Prosnitz wrote:

tl;dr: it is now possible to specify required rights on handles in FIDL files


Hi Team,


After 1 frozening and 1.5 years, handle rights can now be specified in FIDL files and be validated (along with object type) in all FIDL bindings. Rights annotations help to improve security by better aligning expectations with reality.

Benjamin Prosnitz

unread,
Jun 15, 2021, 12:43:55 PM6/15/21
to Josh Gargus, fidl-dev
There is no polymorphism around handle type - it checks for the exact type. If you have multiple handle types, you can still use NONE as in: zx.handle:<NONE, zx.rights,TRANSFER>.

Thanks for pointing out that TRANSFER is always required and may not need to be specified - I hadn't thought about this. I have mixed feelings about this but I lean towards keeping the same behavior and requiring TRANSFER to always be specified until it is clear from experience that it is really annoying. I suspect that in practice constants will often be used to specify rights which I think will make it less troublesome and it seems good to avoid special cases as much as possible. Who knows, it is also possible that FIDL might add a DUPLICATE mode at some point for sending handles.

The sentence "Client and server ends have object type CHANNEL and rights zx.DEFAULT_CHANNEL_RIGHTS". This means if you have a "protocol P" then P and request<P> will each have rights zx.DEFAULT_CHANNEL_RIGHTS. Does that make sense?

Benjamin Prosnitz | Software Engineer | bpro...@google.com | 917-293-4452

Josh Gargus

unread,
Jun 15, 2021, 12:48:30 PM6/15/21
to Benjamin Prosnitz, fidl-dev
It sounds reasonable to keep TRANSFER explicit for now: there shouldn't be migration headaches if we want to later make it the default.

What you say about client and server ends is clear, not sure why I was confused the first time.

Cheers,
Josh
Reply all
Reply to author
Forward
0 new messages