Re: Capsicum revocable (proxy) file descriptors

From: Vinícius_dos_Santos_Oliveira <vini.ipsmaker_at_gmail.com>
Date: Wed, 08 Oct 2025 17:42:34 UTC
Em qua., 8 de out. de 2025 às 14:12, Gleb Popov <arrowd@freebsd.org> escreveu:
> I'm now even more confused. [...] Do you have some high-level usecase example?

Okay, I'll draft something simple to get the ball rolling. How about a
function to create two file descriptors (in a similar fashion as
pipe/socketpair) out of an oldfd (in a similar fashion as dup)?

int revokfd_create(int oldfd, int newfds[2]);
int revokfd_revoke(int masterfd);

revokfd_create would create a pair of two associated file descriptors.
One of them is the proxy and the other is the revoker. The proxy would
just forward every call to oldfd. It can be used in any place where
you'd use oldfd.

revokfd_revoke would be called on the revoker fd (that you keep
private on your process and never pass around) and block until current
proxy operations return. Future operations on the proxy fd will return
ENOTCAPABLE. revokfd_revoke could be an ioctl under the hood so we
don't need a real syscall here.

You can pass the proxy fd around to as if it were the oldfd and revoke
it later in much the same vein as it happens with capabilities in
general: http://wiki.erights.org/wiki/Walnut/Secure_Distributed_Computing/Capability_Patterns#Revocable_Capabilities

In the Firefox FlatPak portal example, the thing implementing the file
dialog and the D-Bus API would open the file for write, call
revokfd_create() to a get a new (proxy) fd for the actual file,
probably use cap_rights_limit() to forbid openat() and mmap(), and
pass that to the Firefox process. Once the user wants to shutdown the
file dialog server process, it'll call revokfd_revoke on all revoker
fds to block Firefox (and/or others) from having write access to user
dirs.