1Mach IPC Security concepts 2========================== 3 4This documentation aims at documenting various security concepts in this 5subsystem. Each section covers a single concept, and will cover topics such as 6motivation, design of the feature, and implementation details that are 7important. 8 9 10## IPC space policy 11 12### Motivation and design 13 14Over time our IPC policies have grown in complexity and depend on several 15parameters, to name a few: being a simulated process, a platform binary, or 16having browser entitlements. 17 18As a result, a notion of IPC space policy exists that projects all various 19system policies into a single enum per IPC space. This policy is an inherent 20immutable property of an IPC space which allows to query its value without 21holding any locks. 22 23 24### Implementation details 25 26The source of truth for IPC policies is the `struct ipc_space::is_policy` field, 27which can be accessed with the `ipc_space_policy()` accessor. 28 29This field is computed when a task IPC space is enabled (in 30`ipc_task_enable()`), and is immutable for the lifetime of this space. In 31addition to that, the field is dPACed in order to be resilient to early memory 32corruption primitives. 33 34For conveniency reasons, the policy bits of a space are injected in other enums 35(such as `mach_msg_options64_t`). The `IPC_SPACE_POLICY_BASE()` macro helps 36forming types that extend the space policy. 37 38 39## Pinned Entries 40 41### Motivation and design 42 43Certain kinds of send rights have a well understood lifecycle on the system, 44during which there must always be an extent send right alive for the port. 45Obvious examples of this are task or thread control ports which must have 46a live send right in their corresponding IPC space while the task or thread 47they reference is alive. 48 49In order to catch port management issues that could lead to various confused 50deputies issues, the Mach IPC subsystem provides a notion of pinned send rights. 51Pinned send rights is a concept of the Mach IPC Entry, which denotes that this 52entry must always have at least one extent send right alive. 53 54Pinning can be undone in two ways: 55 56- when a port receive right is destroyed, pinning is no longer effective, 57 and entries will be automatically unpinned as part of the dead-name check; 58- unpinning can be explicitly requested by the kernel. 59 60 61### When and how to used pinned rights? 62 63Pinned rights were designed to protect `mach_task_self()` and 64`_pthread_mach_thread_self_direct()` which can lead to grave security bugs when 65port lifecycle management mistakes are made. The bracketing there is very 66simple: 67 68- task ports are never unpinned; 69- thread ports are unpinned when the thread terminates. 70 71 72There might be other ports on the system which can use this facility, however 73they must have the right shape: either the port dying (the receive right being 74destroyed) is an adequate way to unpin the entry, or there must be a clearly 75identified kernel path that can unpin the entry without any confusion with other 76ports. 77 78Adding unpinning paths that can't verify that the port being unpinned is 79"theirs" would lead to weakening this feature and would reintroduce avenues 80to confuse the system due to port mismanagement bugs. 81 82 83### Implementation details 84 85Pinning is denoted by the `IE_BITS_PINNED_SEND` bit 86of the `struct ipc_entry::ie_bits` field. 87 88IPC entries gain this bit the first time the kernel calls 89`ipc_port_copyout_send_pinned()` for a given port and IPC space. 90 91When the `IE_BITS_PINNED_SEND` is set, then the `MACH_PORT_TYPE_SEND` bit must 92be set too, with the `IE_BITS_UREFS()` for this entry being at least 1. 93 94In order to respect that pinning is ignored immediately when a port becomes 95dead, enforcing `IE_BITS_PINNED_SEND` semantics must be done under the space 96lock, either right after a dead-name conversion check happened 97(`ipc_right_check()` has been called) or by checking explicitly that the port 98is still active (`ip_active()` returns true) when a dead-name conversion isn't 99desirable. 100 101 102### Usage and enforcement 103 104Task and thread control ports are pinned for all processes within the 105owning IPC space of the task in question, for all processes on the system. 106 107The `ipc_control_port_options` boot-arg determines the reaction of the system to 108violations of pinning: 109 110- hardened processes and above have hard enforcement of pinning rules (violating 111 the rules terminates the process); 112- other processes have a soft enforcement: violating pinning rules returns a 113 `KERN_INVALID_CAPABILITY` error and generates a non fatal guard exception. 114 115 116 117