On this page
Process Protection
The AccessCheck section described PIP protecting objects — files, registry keys, tokens — from processes that lack sufficient trust. This section describes PIP protecting processes — their memory, their execution, their metadata — from other processes.
Process-to-process operations are gated by two independent checks, both of which MUST pass:
- Process SD check — an AccessCheck evaluation of the caller's token against the target process's Security Descriptor (see §5.3). This determines who can perform operations on the process.
- PIP dominance check — a direct comparison of the caller's and target's PSB pip_type/pip_trust fields. This determines which trust level is required. PIP does not use AccessCheck, does not read Security Descriptors, and does not involve the DACL pipeline — it is a standalone binary dominance test.
SeDebugPrivilege bypasses only check 1 (the process SD). It MUST NOT bypass check 2 (PIP dominance). See §8.2 for details.
The two checks complement each other. The process SD controls who can access the process (identity-based). PIP controls which trust level is required (signing-based). Object PIP protection (via trust label ACEs in SACLs) prevents a non-dominant process from opening authd's private key file. Process PIP protection prevents the same process from reading the key directly out of authd's memory via ptrace, or killing authd with a signal.
§8.1.1 The dominance check
Every process isolation check reduces to one question: does the caller's PSB dominate the target's PSB?
pip_dominates(caller_psb, target_psb) -> bool:
if target_psb.pip_type == None:
return true // Unprotected target — any caller dominates.
return caller_psb.pip_type >= target_psb.pip_type
AND caller_psb.pip_trust >= target_psb.pip_trust
PIP types form a total order by their numeric values. None (0), Protected (512), and Isolated (1024) are the conventional tiers used by v0.20, but pip_type is not a closed enum: nonzero values are compared directly as numeric protection tiers. PIP trust levels are also numeric and compared directly (higher = more trusted). The early return for pip_type = None ensures that unprotected processes are always accessible regardless of trust values. The two-dimension check applies whenever the target pip_type is nonzero.
PIP dominance is binary: dominate or don't. If you don't dominate, you have no process access via PIP — the operation is denied regardless of which specific operation was attempted. The process SD provides per-operation granularity (different access rights for signals vs memory vs metadata); PIP is the all-or-nothing gate on top of the SD check. Both MUST pass.