Similar in spirit to process descriptors, jail descriptors are a reference to a jail using the file interface.
Jail descriptors can be created along with the underlying prison with jail_set(2), or fetched later with jail_get(2). They can then be used instead of the jid when a jail is used, via the new system calls jd_attach(2) and jd_remove(2), and also via the "desc" parameter in jail_get(2) and jail_set(2).
Jail_set and jail_get can both create a new descriptor or reference an existing one, controlled by flags. JAIL_USE_DESC reads the desc parameter for a descriptor of the jail to operate on. JAIL_AT_DESC specifies instead the jail to operate under, for example the namespace where to find/create a jail, and the permissions to pass to it. JAIL_GET_DESC will return a new descriptor in the desc parameter (even in jail_set which normally doesn't return parameters), and JAIL_OWN_DESC with return that descriptor with the sticky bit set.
Jail descriptors eliminate the race problem where a jail with a given ID may be destroyed and re-created, and not be the same jail that was referred to before. A descriptor always refers to a single jail over (and beyond) its lifetime, and it is an error to try use an existing descriptor to create a jail. So when a the jail on a descriptor claims to be dead, you can be sure it stays that way.
Permission for jail operations using descriptors is checked against the credentials of the process that first created the descriptor. This allows passing of jail descriptors to non-privileged users who could then for instance attach to a jail without being root. In addition to the privilege checks, the descriptor access mode is also checked, allowing per-user/group and per-operation controls. Read bits control jail_get, write bits control jail_set, and execute bits control jail_attach and the JAIL_AT_DEC flag.
The descriptor sticky bit is repurposed to indicate an owning descriptor, where the jail lifetime is now tied ("stuck") to the descriptor. When the descriptor closes, do will the attached jail. This is similar to the default behavior of process descriptors.
Jail descriptors can be followed via kevent, with the following note types:
- NOTE_JAIL_SET: jail_set has been called. It's up to the user to see what if anything has actually changed.
- NOTE_JAIL_ATTACH: a process has attached to the jail. The note data contains the pid.
- NOTE_JAIL_REMOVE: the jail has been removed. The descriptor remains open, but is no longer attached to the jail.
- NOTE_JAIL_CREATE: a child has been created under the watched jail. The note data contains the child's jid.
Future plans, not yet done:
- Capsicum support
- documentation