1*84c42f51SDaniel Borkmann.. SPDX-License-Identifier: GPL-2.0 2*84c42f51SDaniel Borkmann 3*84c42f51SDaniel Borkmann============ 4*84c42f51SDaniel BorkmannBPF signing 5*84c42f51SDaniel Borkmann============ 6*84c42f51SDaniel Borkmann 7*84c42f51SDaniel BorkmannThis document describes how BPF programs are cryptographically signed, how the 8*84c42f51SDaniel Borkmannkernel verifies them at load time, and how Linux Security Modules (LSMs) - 9*84c42f51SDaniel Borkmannincluding the BPF LSM - use the resulting verdict to enforce policy. It is 10*84c42f51SDaniel Borkmannwritten for developers who want to produce signed BPF objects, understand what 11*84c42f51SDaniel Borkmannthe signature actually guarantees, or build a policy on top of it. 12*84c42f51SDaniel Borkmann 13*84c42f51SDaniel BorkmannMotivation 14*84c42f51SDaniel Borkmann========== 15*84c42f51SDaniel Borkmann 16*84c42f51SDaniel BorkmannA signed BPF program lets the kernel establish that the bytecode being loaded 17*84c42f51SDaniel Borkmannoriginates from a trusted producer and was not modified in transit. On its own 18*84c42f51SDaniel Borkmannthe kernel does not *require* signatures - an unsigned program loads exactly as 19*84c42f51SDaniel Borkmannbefore - but it records a verdict (see `The verdict`_) that an LSM can gate on. 20*84c42f51SDaniel BorkmannThis is the building block for policies such as "only run BPF that was signed by 21*84c42f51SDaniel Borkmanna key in the trusted keyring", as could in the future be enforced by an LSM 22*84c42f51SDaniel Borkmannsuch as IPE. 23*84c42f51SDaniel Borkmann 24*84c42f51SDaniel BorkmannSigning is orthogonal to the existing permission model: it does not replace the 25*84c42f51SDaniel Borkmanncapability checks or the verifier. A signed load still requires the usual 26*84c42f51SDaniel Borkmannprivileges (``CAP_BPF`` and any program-type-specific capability, subject to 27*84c42f51SDaniel Borkmann``kernel.unprivileged_bpf_disabled``), and the loader's instructions are still 28*84c42f51SDaniel Borkmannchecked by the verifier like any other program. A valid signature establishes 29*84c42f51SDaniel Borkmann*origin and integrity*, not safety - it lets a policy trust where the bytecode 30*84c42f51SDaniel Borkmanncame from, it does not let a load skip any check it would otherwise face. 31*84c42f51SDaniel Borkmann 32*84c42f51SDaniel BorkmannThe hard part is *what* gets signed. A naive scheme would sign a program's 33*84c42f51SDaniel Borkmanninstruction buffer at build time and verify that signature at 34*84c42f51SDaniel Borkmann``BPF_PROG_LOAD``. That does not survive contact with real BPF objects, because 35*84c42f51SDaniel Borkmannthe bytes the kernel finally loads are not the bytes the developer built and 36*84c42f51SDaniel Borkmannsigned. Between the two, libbpf and the kernel rewrite the program: 37*84c42f51SDaniel Borkmann 38*84c42f51SDaniel Borkmann- **map file descriptors** are patched into ``ld_imm64`` instructions 39*84c42f51SDaniel Borkmann (``BPF_PSEUDO_MAP_FD``), and a map's fd is assigned at load time, so it 40*84c42f51SDaniel Borkmann differs on every run; 41*84c42f51SDaniel Borkmann- **CO-RE relocations** rewrite field offsets, sizes and existence flags against 42*84c42f51SDaniel Borkmann the *running* kernel's BTF, so the result differs from one kernel to the next; 43*84c42f51SDaniel Borkmann- **kfunc and ksym references** are resolved to ids/addresses in the running 44*84c42f51SDaniel Borkmann kernel; 45*84c42f51SDaniel Borkmann- **global data** (``.rodata``/``.data``/``.bss``) is created and seeded as maps 46*84c42f51SDaniel Borkmann at load. 47*84c42f51SDaniel Borkmann 48*84c42f51SDaniel BorkmannSo a signature over the original instructions cannot match the relocated 49*84c42f51SDaniel Borkmanninstructions the verifier ends up checking, and the relocated form cannot be 50*84c42f51SDaniel Borkmannproduced ahead of time because it depends on the target kernel. There is no 51*84c42f51SDaniel Borkmannfixed byte string that is both signable at build time and what the kernel 52*84c42f51SDaniel Borkmannactually loads - which is why a program cannot simply be signed and loaded 53*84c42f51SDaniel Borkmanndirectly. 54*84c42f51SDaniel Borkmann 55*84c42f51SDaniel BorkmannThe trusted loader 56*84c42f51SDaniel Borkmann================== 57*84c42f51SDaniel Borkmann 58*84c42f51SDaniel BorkmannThe solution is to move that setup work *into* a small BPF program - the 59*84c42f51SDaniel Borkmann**loader** - and sign the loader instead of the individual programs. libbpf's 60*84c42f51SDaniel Borkmann``gen_loader`` machinery (``bpftool gen skeleton -L``, the "light skeleton") 61*84c42f51SDaniel Borkmannemits a ``BPF_PROG_TYPE_SYSCALL`` program whose body performs the bpf() syscalls 62*84c42f51SDaniel Borkmannthat create maps, apply relocations, and load the real programs. The payload it 63*84c42f51SDaniel Borkmanninstalls - the serialized programs, map descriptions, relocation data and 64*84c42f51SDaniel Borkmanninitial values - lives in a separate array map, the **metadata map** 65*84c42f51SDaniel Borkmann(``__loader.map``). 66*84c42f51SDaniel Borkmann 67*84c42f51SDaniel BorkmannSo the unit of trust is the loader, and the signing contract is:: 68*84c42f51SDaniel Borkmann 69*84c42f51SDaniel Borkmann Sig(I_loader || D_meta) 70*84c42f51SDaniel Borkmann 71*84c42f51SDaniel Borkmannwhere ``I_loader`` is the loader's instruction stream and ``D_meta`` is the 72*84c42f51SDaniel Borkmanncontent of the metadata map. Verifying the loader's signature establishes that 73*84c42f51SDaniel Borkmannboth the loader *and* the payload it is about to install are authentic. The 74*84c42f51SDaniel Borkmannloader is reproducible: ``gen_loader`` builds it from primitives so the same 75*84c42f51SDaniel Borkmannobject yields the same bytes on any build host. 76*84c42f51SDaniel Borkmann 77*84c42f51SDaniel BorkmannWhy the loader is signable when the program is not 78*84c42f51SDaniel Borkmann-------------------------------------------------- 79*84c42f51SDaniel Borkmann 80*84c42f51SDaniel BorkmannThe loader sidesteps every rewrite listed above, because the bytes that are 81*84c42f51SDaniel Borkmannsigned are *relocation-invariant*: 82*84c42f51SDaniel Borkmann 83*84c42f51SDaniel Borkmann- The loader's own instructions are a fixed sequence of bpf() syscalls emitted 84*84c42f51SDaniel Borkmann by ``gen_loader``; they carry no CO-RE relocations and resolve no ksyms, so 85*84c42f51SDaniel Borkmann they are identical on every kernel. The metadata map is referenced by *index* 86*84c42f51SDaniel Borkmann into ``fd_array`` (``BPF_PSEUDO_MAP_IDX_VALUE``), not by a baked-in file 87*84c42f51SDaniel Borkmann descriptor, so even that reference does not change between build and load. 88*84c42f51SDaniel Borkmann The loader instruction bytes the kernel verifies are exactly the bytes that 89*84c42f51SDaniel Borkmann were signed. 90*84c42f51SDaniel Borkmann- The metadata map is opaque, frozen data - the serialized target programs, 91*84c42f51SDaniel Borkmann their relocation records, map descriptions and initial values. Its bytes are 92*84c42f51SDaniel Borkmann identical at build time and at load time, so they are simply appended to the 93*84c42f51SDaniel Borkmann instructions and covered by the same signature (there is no separate metadata 94*84c42f51SDaniel Borkmann hash to compute or compare). 95*84c42f51SDaniel Borkmann 96*84c42f51SDaniel BorkmannAll the host-specific rewriting - creating maps, patching their fds into the 97*84c42f51SDaniel Borkmanntarget programs, applying CO-RE, resolving ksyms, seeding global data - still 98*84c42f51SDaniel Borkmannhappens, but it happens *inside the loader at runtime*, on the verified 99*84c42f51SDaniel Borkmannmetadata, **after** the kernel has verified the ``insns || metadata`` signature. 100*84c42f51SDaniel BorkmannThe kernel never has to verify the relocated target programs: it verifies the 101*84c42f51SDaniel Borkmannloader and its inputs once, and trust transfers to whatever that now-trusted, 102*84c42f51SDaniel Borkmanndeterministic loader installs. The relocation step is moved from "before the 103*84c42f51SDaniel Borkmannsignature can be checked" to "after a trusted program runs" - which is exactly 104*84c42f51SDaniel Borkmannwhat makes it signable. 105*84c42f51SDaniel Borkmann 106*84c42f51SDaniel BorkmannBecause the metadata map is the loader's only untrusted input, two existing map 107*84c42f51SDaniel Borkmannproperties are reused to keep it trustworthy across the load: 108*84c42f51SDaniel Borkmann 109*84c42f51SDaniel BorkmannExclusive maps 110*84c42f51SDaniel Borkmann A map created with ``excl_prog_hash`` (see ``BPF_MAP_CREATE``) may only be 111*84c42f51SDaniel Borkmann accessed by a program whose digest matches that hash. The verifier enforces 112*84c42f51SDaniel Borkmann ``map->excl_prog_sha == prog->digest`` for every map a program uses, so the 113*84c42f51SDaniel Borkmann metadata map is bound to exactly the signed loader and cannot be shared with 114*84c42f51SDaniel Borkmann or mutated by another program. 115*84c42f51SDaniel Borkmann 116*84c42f51SDaniel BorkmannFrozen maps 117*84c42f51SDaniel Borkmann The metadata map is frozen (``BPF_MAP_FREEZE``) before the loader is loaded. 118*84c42f51SDaniel Borkmann Freezing blocks further userspace writes, so the bytes folded into the 119*84c42f51SDaniel Borkmann signature cannot change before the loader runs. (Freezing does not make the 120*84c42f51SDaniel Borkmann map read-only to the loader program itself, which still writes created file 121*84c42f51SDaniel Borkmann descriptors back into the blob's scratch area.) 122*84c42f51SDaniel Borkmann 123*84c42f51SDaniel BorkmannLoad-time verification 124*84c42f51SDaniel Borkmann======================= 125*84c42f51SDaniel Borkmann 126*84c42f51SDaniel BorkmannRather than have the loader check its own metadata from within BPF, the kernel 127*84c42f51SDaniel Borkmannverifies it directly at ``BPF_PROG_LOAD``, with no new UAPI. The mechanism 128*84c42f51SDaniel Borkmannreuses the existing ``fd_array``: 129*84c42f51SDaniel Borkmann 130*84c42f51SDaniel Borkmann#. Userspace creates the metadata map with ``excl_prog_hash`` set to the 131*84c42f51SDaniel Borkmann loader's digest, populates it, and freezes it. 132*84c42f51SDaniel Borkmann#. The loader is loaded with ``signature``/``signature_size``/``keyring_id`` 133*84c42f51SDaniel Borkmann set, the metadata map referenced through ``fd_array``, and ``fd_array_cnt`` 134*84c42f51SDaniel Borkmann set so the kernel knows the array's length. 135*84c42f51SDaniel Borkmann#. Signature verification runs inside the verifier (``bpf_check()``), once it 136*84c42f51SDaniel Borkmann has resolved the ``fd_array`` entries into the program's ``used_maps``. The 137*84c42f51SDaniel Borkmann maps folded into the signature are therefore the very objects the program 138*84c42f51SDaniel Borkmann binds - a single resolution of ``fd_array``, not a separate read, so the 139*84c42f51SDaniel Borkmann verified bytes cannot be swapped for a different map after the check (no 140*84c42f51SDaniel Borkmann time-of-check/time-of-use window). Each folded map must be exclusive (carry 141*84c42f51SDaniel Borkmann ``excl_prog_sha``) and a plain array map (``BPF_MAP_TYPE_ARRAY``); only an 142*84c42f51SDaniel Borkmann array map exposes its value buffer through ``map_direct_value_addr()`` as a 143*84c42f51SDaniel Borkmann kernel address spanning ``value_size`` bytes. A map that is not exclusive, not 144*84c42f51SDaniel Borkmann frozen, or not a plain array is rejected, with a verifier log message naming 145*84c42f51SDaniel Borkmann the offending map. The kernel appends each map's frozen 146*84c42f51SDaniel Borkmann contents to the instruction buffer and verifies the PKCS#7 signature over the 147*84c42f51SDaniel Borkmann concatenation ``insns || metadata_0 || metadata_1 || ...`` in ``used_maps`` 148*84c42f51SDaniel Borkmann order, before it rewrites the (signed) instructions. 149*84c42f51SDaniel Borkmann 150*84c42f51SDaniel BorkmannA signed program therefore takes one of exactly two shapes, both fully 151*84c42f51SDaniel Borkmannsupported: 152*84c42f51SDaniel Borkmann 153*84c42f51SDaniel Borkmann- **No bound maps** (``fd_array_cnt == 0``): there is nothing to append, so the 154*84c42f51SDaniel Borkmann kernel verifies the signature over the instructions alone. A valid signature 155*84c42f51SDaniel Borkmann yields ``BPF_SIG_VERIFIED`` and the program loads. This is the ordinary case 156*84c42f51SDaniel Borkmann for a directly-loaded signed program with no separate payload; it is *not* 157*84c42f51SDaniel Borkmann rejected for "missing" metadata, because it has none to cover. 158*84c42f51SDaniel Borkmann- **Exclusive bound maps** (``fd_array_cnt > 0``): every entry is exclusive and 159*84c42f51SDaniel Borkmann folded, so the signature covers ``insns || metadata``. 160*84c42f51SDaniel Borkmann 161*84c42f51SDaniel BorkmannThere is no third shape: a non-exclusive map in a signed program's ``fd_array`` 162*84c42f51SDaniel Borkmannis rejected rather than silently left out of the signature, so a signed loader 163*84c42f51SDaniel Borkmannnever binds a map its signature does not cover. 164*84c42f51SDaniel Borkmann 165*84c42f51SDaniel BorkmannThe digest binding (``excl_prog_sha == prog->digest``) is enforced by the 166*84c42f51SDaniel Borkmannverifier as usual; because that check runs while ``fd_array`` is resolved - 167*84c42f51SDaniel Borkmannbefore the verifier would otherwise compute the tag - ``prog->digest`` is 168*84c42f51SDaniel Borkmanncomputed up front in the verifier, over the unmodified (signature-covered) 169*84c42f51SDaniel Borkmanninstructions, for any signed load. 170*84c42f51SDaniel Borkmann 171*84c42f51SDaniel BorkmannCoverage is then enforced as the verifier resolves instructions, at the point 172*84c42f51SDaniel Borkmanneach object is bound rather than by a count taken afterwards. Once the signature 173*84c42f51SDaniel Borkmannhas been verified, binding any further map is refused: a map reached by a 174*84c42f51SDaniel Borkmanndirectly-referenced fd, or a map swapped into an ``fd_array`` slot the loader 175*84c42f51SDaniel Borkmannreads, is not among those already folded, so it is rejected the moment the 176*84c42f51SDaniel Borkmannverifier tries to bind it. A BTF is refused outright for a signed program - a 177*84c42f51SDaniel Borkmannksym or a BTF fd in ``fd_array``, whether resolved up front or lazily for a 178*84c42f51SDaniel Borkmannmodule kfunc, is rejected when it would be bound. Together with the fold rule 179*84c42f51SDaniel Borkmannabove this keeps the verdict binary: a signed program cannot use a map its 180*84c42f51SDaniel Borkmannsignature does not cover, and a different but equally digest-bound map cannot be 181*84c42f51SDaniel Borkmannsubstituted at an ``fd_array`` slot. Non-exclusive maps are never folded, so a 182*84c42f51SDaniel Borkmannsigned program cannot use one at all. 183*84c42f51SDaniel Borkmann 184*84c42f51SDaniel BorkmannThe verdict 185*84c42f51SDaniel Borkmann=========== 186*84c42f51SDaniel Borkmann 187*84c42f51SDaniel BorkmannA program is either unsigned or fully verified - there is no intermediate 188*84c42f51SDaniel Borkmannstate. The outcome is recorded in ``prog->aux->sig.verdict``: 189*84c42f51SDaniel Borkmann 190*84c42f51SDaniel Borkmann.. code-block:: c 191*84c42f51SDaniel Borkmann 192*84c42f51SDaniel Borkmann enum bpf_sig_verdict { 193*84c42f51SDaniel Borkmann BPF_SIG_UNSIGNED = 0, 194*84c42f51SDaniel Borkmann BPF_SIG_VERIFIED, 195*84c42f51SDaniel Borkmann }; 196*84c42f51SDaniel Borkmann 197*84c42f51SDaniel Borkmann``BPF_SIG_VERIFIED`` means the signature is valid and covers the instructions 198*84c42f51SDaniel Borkmann*and* the frozen contents of every exclusive map the program uses: 199*84c42f51SDaniel Borkmann 200*84c42f51SDaniel Borkmann- For an ordinary, directly-loaded signed program the instructions are the whole 201*84c42f51SDaniel Borkmann artifact and it uses no exclusive maps, so a valid instruction signature is 202*84c42f51SDaniel Borkmann the complete verification. 203*84c42f51SDaniel Borkmann- For a signed loader the metadata map is exclusive, so its contents are folded 204*84c42f51SDaniel Borkmann in and the signature covers ``insns || metadata``. 205*84c42f51SDaniel Borkmann 206*84c42f51SDaniel BorkmannThere is deliberately no "instructions verified but metadata not" verdict: a 207*84c42f51SDaniel Borkmannsigned loader that fails to cover its metadata is *rejected* (see above), not 208*84c42f51SDaniel Borkmannrecorded with a weaker verdict. ``BPF_SIG_VERIFIED`` therefore always means the 209*84c42f51SDaniel Borkmannprogram and everything the signature is responsible for are authentic, which is 210*84c42f51SDaniel Borkmannwhat a policy can rely on. 211*84c42f51SDaniel Borkmann 212*84c42f51SDaniel BorkmannAlongside the verdict the kernel records which keyring validated the signature; 213*84c42f51SDaniel Borkmannsee `Keyrings`_. 214*84c42f51SDaniel Borkmann 215*84c42f51SDaniel BorkmannEnforcement via LSMs 216*84c42f51SDaniel Borkmann==================== 217*84c42f51SDaniel Borkmann 218*84c42f51SDaniel BorkmannSigning only *records* a verdict; an LSM turns it into policy. The verdict and 219*84c42f51SDaniel Borkmannkeyring fields live in ``struct bpf_prog_aux``, so a BPF LSM program can read 220*84c42f51SDaniel Borkmannthem directly (see Documentation/bpf/prog_lsm.rst for writing and attaching BPF 221*84c42f51SDaniel BorkmannLSM programs); the same fields are equally available to in-tree LSMs. Two hooks 222*84c42f51SDaniel Borkmannare useful at different points of the load: the dedicated 223*84c42f51SDaniel Borkmann``security_bpf_prog_load()`` gates admission before the main verification work, 224*84c42f51SDaniel Borkmannand the existing ``security_bpf_prog()`` observes a program that has fully 225*84c42f51SDaniel Borkmannloaded. 226*84c42f51SDaniel Borkmann 227*84c42f51SDaniel BorkmannAdmission: ``security_bpf_prog_load()`` 228*84c42f51SDaniel Borkmann--------------------------------------- 229*84c42f51SDaniel Borkmann 230*84c42f51SDaniel BorkmannThis hook gates admission **for every load**, from a single call site inside the 231*84c42f51SDaniel Borkmannverifier (``bpf_check()``), before the main verification work. It runs after the 232*84c42f51SDaniel Borkmannoptional signature verification, so the verdict and keyring fields are final - the 233*84c42f51SDaniel Borkmannhook can see whether, and how strongly, the program was signed, which keyring 234*84c42f51SDaniel Borkmannvalidated it, the load ``attr``, the BPF token and whether the load came from the 235*84c42f51SDaniel Borkmannkernel. For a signed load the verdict is ``BPF_SIG_VERIFIED`` here (the signature 236*84c42f51SDaniel Borkmannhas just been checked); for an unsigned load it is ``BPF_SIG_UNSIGNED``. 237*84c42f51SDaniel Borkmann 238*84c42f51SDaniel BorkmannThis is the place for *coarse admission* that must also see unsigned and 239*84c42f51SDaniel Borkmannnot-yet-verified loads: require a signature at all, restrict the acceptable 240*84c42f51SDaniel Borkmannkeyring, restrict which token/credentials may load BPF, apply per-program-type 241*84c42f51SDaniel Borkmannrules, or audit every load attempt that makes it past signature verification - 242*84c42f51SDaniel Borkmannattempts failing the signature or the metadata binding abort before this hook 243*84c42f51SDaniel Borkmannfires. It is the primary deny point. 244*84c42f51SDaniel Borkmann 245*84c42f51SDaniel BorkmannOne subtlety: this hook runs *before* the verifier finishes its work, so 246*84c42f51SDaniel Borkmann``BPF_SIG_VERIFIED`` *here* means only "validly signed" - not "loaded". Allowing 247*84c42f51SDaniel Borkmanna load at this point lets it *proceed*; it does not guarantee the program will 248*84c42f51SDaniel Borkmannload. A validly signed program can still be rejected afterwards on two 249*84c42f51SDaniel Borkmannindependent grounds: the verifier may reject it like any other program (unsafe 250*84c42f51SDaniel Borkmannmemory access, bad control flow, resource limits, ...), and the kernel separately 251*84c42f51SDaniel Borkmannrefuses - as the verifier resolves instructions and binds each object - any map 252*84c42f51SDaniel Borkmannthe signature does not cover or any BTF at all, regardless of what this hook 253*84c42f51SDaniel Borkmannreturned. Only after the program has fully loaded, at the next hook 254*84c42f51SDaniel Borkmann(``security_bpf_prog()``), does ``BPF_SIG_VERIFIED`` carry its full meaning: 255*84c42f51SDaniel Borkmannvalidly signed *and* fully verified. 256*84c42f51SDaniel Borkmann 257*84c42f51SDaniel BorkmannA more realistic admission policy than "is it signed at all": accept programs 258*84c42f51SDaniel Borkmannsigned by a system keyring, accept a user-keyring signature only if the 259*84c42f51SDaniel Borkmannkey/keyring it was verified against is on an explicit allowlist, and emit a 260*84c42f51SDaniel Borkmanntamper-evident record of every decision so that even denied attempts are 261*84c42f51SDaniel Borkmannauditable. (Illustrative - error checking elided.) 262*84c42f51SDaniel Borkmann 263*84c42f51SDaniel Borkmann.. code-block:: c 264*84c42f51SDaniel Borkmann 265*84c42f51SDaniel Borkmann /* Serials of user keys/keyrings we additionally trust. */ 266*84c42f51SDaniel Borkmann struct { 267*84c42f51SDaniel Borkmann __uint(type, BPF_MAP_TYPE_HASH); 268*84c42f51SDaniel Borkmann __type(key, __s32); /* keyring_serial */ 269*84c42f51SDaniel Borkmann __type(value, __u8); 270*84c42f51SDaniel Borkmann __uint(max_entries, 64); 271*84c42f51SDaniel Borkmann } trusted_user_keys SEC(".maps"); 272*84c42f51SDaniel Borkmann 273*84c42f51SDaniel Borkmann /* Audit stream consumed by a userspace logger. */ 274*84c42f51SDaniel Borkmann struct { 275*84c42f51SDaniel Borkmann __uint(type, BPF_MAP_TYPE_RINGBUF); 276*84c42f51SDaniel Borkmann __uint(max_entries, 1 << 16); 277*84c42f51SDaniel Borkmann } audit SEC(".maps"); 278*84c42f51SDaniel Borkmann 279*84c42f51SDaniel Borkmann struct decision { __u32 prog_type, verdict, ktype; __s32 serial, ret; }; 280*84c42f51SDaniel Borkmann 281*84c42f51SDaniel Borkmann SEC("lsm/bpf_prog_load") 282*84c42f51SDaniel Borkmann int BPF_PROG(admit, struct bpf_prog *prog, union bpf_attr *attr, 283*84c42f51SDaniel Borkmann struct bpf_token *token, bool kernel) 284*84c42f51SDaniel Borkmann { 285*84c42f51SDaniel Borkmann __u32 verdict = prog->aux->sig.verdict; 286*84c42f51SDaniel Borkmann __u32 ktype = prog->aux->sig.keyring_type; 287*84c42f51SDaniel Borkmann __s32 serial = prog->aux->sig.keyring_serial; 288*84c42f51SDaniel Borkmann struct decision *d; 289*84c42f51SDaniel Borkmann int ret = 0; 290*84c42f51SDaniel Borkmann 291*84c42f51SDaniel Borkmann if (kernel) 292*84c42f51SDaniel Borkmann return 0; /* trust in-kernel loads */ 293*84c42f51SDaniel Borkmann 294*84c42f51SDaniel Borkmann if (verdict != BPF_SIG_VERIFIED) 295*84c42f51SDaniel Borkmann ret = -EPERM; /* must be validly signed */ 296*84c42f51SDaniel Borkmann else if (ktype == BPF_SIG_KEYRING_USER && 297*84c42f51SDaniel Borkmann !bpf_map_lookup_elem(&trusted_user_keys, &serial)) 298*84c42f51SDaniel Borkmann ret = -EPERM; /* key/keyring not allowlisted */ 299*84c42f51SDaniel Borkmann 300*84c42f51SDaniel Borkmann d = bpf_ringbuf_reserve(&audit, sizeof(*d), 0); 301*84c42f51SDaniel Borkmann if (d) { 302*84c42f51SDaniel Borkmann d->prog_type = attr->prog_type; 303*84c42f51SDaniel Borkmann d->verdict = verdict; 304*84c42f51SDaniel Borkmann d->ktype = ktype; 305*84c42f51SDaniel Borkmann d->serial = serial; 306*84c42f51SDaniel Borkmann d->ret = ret; 307*84c42f51SDaniel Borkmann bpf_ringbuf_submit(d, 0); /* record allow *and* deny */ 308*84c42f51SDaniel Borkmann } 309*84c42f51SDaniel Borkmann return ret; 310*84c42f51SDaniel Borkmann } 311*84c42f51SDaniel Borkmann 312*84c42f51SDaniel BorkmannObserving a verified load: ``security_bpf_prog()`` 313*84c42f51SDaniel Borkmann-------------------------------------------------- 314*84c42f51SDaniel Borkmann 315*84c42f51SDaniel BorkmannThere is deliberately no separate "metadata attested" hook. The coverage check 316*84c42f51SDaniel Borkmannabove is enforced by the kernel unconditionally, so a signed loader that fails 317*84c42f51SDaniel Borkmannto cover its metadata never loads and an LSM never has to re-establish that 318*84c42f51SDaniel Borkmannfact. To *act on* a program that has successfully and fully loaded, use the 319*84c42f51SDaniel Borkmannexisting ``security_bpf_prog()`` hook (``lsm/bpf_prog``), which fires from 320*84c42f51SDaniel Borkmann``bpf_prog_new_fd()`` - after the verifier, after the coverage check, and after 321*84c42f51SDaniel Borkmann``bpf_prog_alloc_id()``. Relative to the admission hook this point is strictly 322*84c42f51SDaniel Borkmannlater and stronger: 323*84c42f51SDaniel Borkmann 324*84c42f51SDaniel Borkmann- the program has an id (``prog->aux->id``), so it can be recorded or correlated 325*84c42f51SDaniel Borkmann with later events; 326*84c42f51SDaniel Borkmann- ``verdict == BPF_SIG_VERIFIED`` *here* means **fully** verified - a program 327*84c42f51SDaniel Borkmann that used a map the signature does not cover was already rejected, so it cannot 328*84c42f51SDaniel Borkmann reach this point; 329*84c42f51SDaniel Borkmann- it observes only programs that actually loaded; a failed load never mints an 330*84c42f51SDaniel Borkmann fd, so it never reaches this hook. 331*84c42f51SDaniel Borkmann 332*84c42f51SDaniel BorkmannIt takes only the ``prog`` and a non-zero return still aborts (the fd is not 333*84c42f51SDaniel Borkmannhanded out), so it can veto as well as observe. One wrinkle: it also fires on 334*84c42f51SDaniel Borkmannother paths that mint a new program fd - notably ``bpf_prog_get_fd_by_id()`` - 335*84c42f51SDaniel Borkmannnot just on a fresh load. Because the program already has its id here, an LSM 336*84c42f51SDaniel Borkmanncan tell the two apart with a small hash map: the *first* time an id is seen is 337*84c42f51SDaniel Borkmannthe load; a later sighting of the same id is just another fd to a program that 338*84c42f51SDaniel Borkmannalready exists. 339*84c42f51SDaniel Borkmann 340*84c42f51SDaniel BorkmannTo bound the map and let a reused id read as a fresh load, this can be paired 341*84c42f51SDaniel Borkmannwith ``security_bpf_prog_free()`` (``lsm/bpf_prog_free``), which deletes the 342*84c42f51SDaniel Borkmannentry on teardown - keyed by the same ``prog`` pointer, since 343*84c42f51SDaniel Borkmann``bpf_prog_free_id()`` has already cleared ``prog->aux->id`` to ``0`` by the time 344*84c42f51SDaniel Borkmannthat hook runs. (Illustrative - privileged LSM, error checking elided.) 345*84c42f51SDaniel Borkmann 346*84c42f51SDaniel Borkmann.. code-block:: c 347*84c42f51SDaniel Borkmann 348*84c42f51SDaniel Borkmann struct rec { __u32 id, ktype; __s32 serial; }; 349*84c42f51SDaniel Borkmann 350*84c42f51SDaniel Borkmann struct { 351*84c42f51SDaniel Borkmann __uint(type, BPF_MAP_TYPE_HASH); 352*84c42f51SDaniel Borkmann __type(key, __u64); /* struct bpf_prog * -- stable id */ 353*84c42f51SDaniel Borkmann __type(value, struct rec); 354*84c42f51SDaniel Borkmann __uint(max_entries, 4096); 355*84c42f51SDaniel Borkmann } live SEC(".maps"); 356*84c42f51SDaniel Borkmann 357*84c42f51SDaniel Borkmann SEC("lsm/bpf_prog") /* fires after load and on every later fd */ 358*84c42f51SDaniel Borkmann int BPF_PROG(observe, struct bpf_prog *prog) 359*84c42f51SDaniel Borkmann { 360*84c42f51SDaniel Borkmann __u64 key = (__u64)(unsigned long)prog; 361*84c42f51SDaniel Borkmann struct rec r; 362*84c42f51SDaniel Borkmann 363*84c42f51SDaniel Borkmann if (prog->aux->sig.verdict != BPF_SIG_VERIFIED) 364*84c42f51SDaniel Borkmann return 0; 365*84c42f51SDaniel Borkmann if (bpf_map_lookup_elem(&live, &key)) 366*84c42f51SDaniel Borkmann return 0; /* seen before: a later fd, not a load */ 367*84c42f51SDaniel Borkmann 368*84c42f51SDaniel Borkmann /* First sighting == this program just loaded; id is valid here. */ 369*84c42f51SDaniel Borkmann r.id = prog->aux->id; 370*84c42f51SDaniel Borkmann r.ktype = prog->aux->sig.keyring_type; 371*84c42f51SDaniel Borkmann r.serial = prog->aux->sig.keyring_serial; 372*84c42f51SDaniel Borkmann bpf_map_update_elem(&live, &key, &r, BPF_NOEXIST); 373*84c42f51SDaniel Borkmann /* ... newly-loaded verified-program action, e.g. record r.id ... */ 374*84c42f51SDaniel Borkmann return 0; 375*84c42f51SDaniel Borkmann } 376*84c42f51SDaniel Borkmann 377*84c42f51SDaniel BorkmannPutting them together: to *require* verified BPF, deny at the admission hook 378*84c42f51SDaniel Borkmannunless the verdict is ``BPF_SIG_VERIFIED`` (and, if desired, restrict the 379*84c42f51SDaniel Borkmannkeyring). The kernel then guarantees that any program which actually loads with 380*84c42f51SDaniel Borkmannthat verdict covered all of its exclusive maps, rejecting any that did not - so 381*84c42f51SDaniel Borkmanna deny-by-default admission policy needs no second enforcement point. Use 382*84c42f51SDaniel Borkmann``security_bpf_prog()`` to record or finally gate the verified programs once 383*84c42f51SDaniel Borkmannthey carry an id. The ``verdict``, ``keyring_type`` and ``keyring_serial`` fields 384*84c42f51SDaniel Borkmannlet a policy distinguish, for example, "verified and signed by a builtin key" 385*84c42f51SDaniel Borkmannfrom "verified by a user key". A policy LSM such as IPE could consume the same 386*84c42f51SDaniel Borkmannhooks to enforce system policy without writing any BPF, though none implements 387*84c42f51SDaniel Borkmannthis today. 388*84c42f51SDaniel Borkmann 389*84c42f51SDaniel BorkmannKeyrings 390*84c42f51SDaniel Borkmann======== 391*84c42f51SDaniel Borkmann 392*84c42f51SDaniel Borkmann``keyring_id`` selects the trusted keyring the PKCS#7 signature is verified 393*84c42f51SDaniel Borkmannagainst. The well-known ids ``0`` (builtin), ``VERIFY_USE_SECONDARY_KEYRING`` 394*84c42f51SDaniel Borkmannand ``VERIFY_USE_PLATFORM_KEYRING`` select the corresponding system keyrings; 395*84c42f51SDaniel Borkmannany other value is treated as the serial of a user/session key or keyring. 396*84c42f51SDaniel BorkmannThe keyring is looked up first, before the signature bytes are examined, so a 397*84c42f51SDaniel Borkmannsignature naming a non-existent keyring is rejected up front, and a failed 398*84c42f51SDaniel Borkmannverification aborts the load - so a program that loads successfully with a 399*84c42f51SDaniel Borkmannsignature always has consistent keyring fields recorded. 400*84c42f51SDaniel Borkmann 401*84c42f51SDaniel BorkmannTwo fields are recorded in ``prog->aux->sig`` for an LSM to inspect: 402*84c42f51SDaniel Borkmann 403*84c42f51SDaniel Borkmann``keyring_type`` (``enum bpf_sig_keyring``) 404*84c42f51SDaniel Borkmann Classified purely from ``keyring_id`` whenever the program is signed: 405*84c42f51SDaniel Borkmann ``BPF_SIG_KEYRING_BUILTIN``, ``_SECONDARY``, ``_PLATFORM`` for the system 406*84c42f51SDaniel Borkmann keyrings, or ``_USER`` for a user/session keyring. It is 407*84c42f51SDaniel Borkmann ``BPF_SIG_KEYRING_NONE`` for an unsigned program. 408*84c42f51SDaniel Borkmann 409*84c42f51SDaniel Borkmann``keyring_serial`` (``s32``) 410*84c42f51SDaniel Borkmann Set **only** on a successful verification, to the serial of the 411*84c42f51SDaniel Borkmann **user/session key or keyring** that ``keyring_id`` resolved to - the 412*84c42f51SDaniel Borkmann object the signature was verified against, not the individual asymmetric 413*84c42f51SDaniel Borkmann key inside it that matched the signer. Passing 414*84c42f51SDaniel Borkmann ``KEY_SPEC_SESSION_KEYRING``, for example, records the session keyring's 415*84c42f51SDaniel Borkmann serial. The system keyrings are trusted as a whole and expose no serial 416*84c42f51SDaniel Borkmann here, so the serial is ``0`` for builtin, secondary and platform 417*84c42f51SDaniel Borkmann signatures, and ``0`` for unsigned programs. In other words, a non-zero 418*84c42f51SDaniel Borkmann ``keyring_serial`` is exactly "verified against the user key/keyring with 419*84c42f51SDaniel Borkmann this serial". 420*84c42f51SDaniel Borkmann 421*84c42f51SDaniel Borkmann.. list-table:: 422*84c42f51SDaniel Borkmann :header-rows: 1 423*84c42f51SDaniel Borkmann 424*84c42f51SDaniel Borkmann * - ``keyring_id`` 425*84c42f51SDaniel Borkmann - ``keyring_type`` 426*84c42f51SDaniel Borkmann - ``keyring_serial`` 427*84c42f51SDaniel Borkmann * - (no signature) 428*84c42f51SDaniel Borkmann - ``BPF_SIG_KEYRING_NONE`` 429*84c42f51SDaniel Borkmann - ``0`` 430*84c42f51SDaniel Borkmann * - ``0`` 431*84c42f51SDaniel Borkmann - ``BPF_SIG_KEYRING_BUILTIN`` 432*84c42f51SDaniel Borkmann - ``0`` 433*84c42f51SDaniel Borkmann * - ``VERIFY_USE_SECONDARY_KEYRING`` 434*84c42f51SDaniel Borkmann - ``BPF_SIG_KEYRING_SECONDARY`` 435*84c42f51SDaniel Borkmann - ``0`` 436*84c42f51SDaniel Borkmann * - ``VERIFY_USE_PLATFORM_KEYRING`` 437*84c42f51SDaniel Borkmann - ``BPF_SIG_KEYRING_PLATFORM`` 438*84c42f51SDaniel Borkmann - ``0`` 439*84c42f51SDaniel Borkmann * - other (a user/session key serial) 440*84c42f51SDaniel Borkmann - ``BPF_SIG_KEYRING_USER`` 441*84c42f51SDaniel Borkmann - serial of the resolved key/keyring 442*84c42f51SDaniel Borkmann 443*84c42f51SDaniel BorkmannProducing a signed object 444*84c42f51SDaniel Borkmann========================== 445*84c42f51SDaniel Borkmann 446*84c42f51SDaniel Borkmann``bpftool`` generates and signs a light skeleton in one step:: 447*84c42f51SDaniel Borkmann 448*84c42f51SDaniel Borkmann bpftool gen skeleton -L -S -k <private_key.pem> -i <certificate.x509> \ 449*84c42f51SDaniel Borkmann obj.bpf.o > obj.lskel.h 450*84c42f51SDaniel Borkmann 451*84c42f51SDaniel Borkmann``-L`` selects the light-skeleton (``gen_loader``) backend and ``-S`` enables 452*84c42f51SDaniel Borkmannsigning; ``-k`` and ``-i`` supply the signing key and its X.509 certificate. 453*84c42f51SDaniel Borkmann``bpftool`` signs ``insns || metadata`` - the exact bytes the kernel 454*84c42f51SDaniel Borkmannreconstructs - and also computes ``excl_prog_hash`` as the digest of the loader 455*84c42f51SDaniel Borkmanninstructions so the metadata map can be bound to the loader. The signature and 456*84c42f51SDaniel Borkmannhash are embedded in the generated header; the certificate is used only for 457*84c42f51SDaniel Borkmannsigning and is not included. Loading the skeleton performs the 458*84c42f51SDaniel Borkmanncreate/populate/freeze/load sequence described above. 459*84c42f51SDaniel Borkmann 460*84c42f51SDaniel BorkmannAt runtime the trusted public key must be present in the chosen keyring (for 461*84c42f51SDaniel Borkmannexample added to the session keyring, or built into the kernel's builtin trusted 462*84c42f51SDaniel Borkmannkeyring) for verification to succeed. 463*84c42f51SDaniel Borkmann 464*84c42f51SDaniel BorkmannUAPI reference 465*84c42f51SDaniel Borkmann============== 466*84c42f51SDaniel Borkmann 467*84c42f51SDaniel Borkmann``BPF_PROG_LOAD`` (``union bpf_attr``): 468*84c42f51SDaniel Borkmann 469*84c42f51SDaniel Borkmann``signature``, ``signature_size`` 470*84c42f51SDaniel Borkmann Pointer to and length of the PKCS#7 signature blob. 471*84c42f51SDaniel Borkmann 472*84c42f51SDaniel Borkmann``keyring_id`` 473*84c42f51SDaniel Borkmann Trusted keyring selector (see `Keyrings`_). 474*84c42f51SDaniel Borkmann 475*84c42f51SDaniel Borkmann``fd_array``, ``fd_array_cnt`` 476*84c42f51SDaniel Borkmann Array of map (and module BTF) file descriptors bound to the program. 477*84c42f51SDaniel Borkmann ``fd_array_cnt`` must be set for the kernel to scan the array. When a 478*84c42f51SDaniel Borkmann signature is present, a BTF entry is rejected outright, and every map must 479*84c42f51SDaniel Borkmann be exclusive; its frozen contents are folded into the verified buffer, and 480*84c42f51SDaniel Borkmann a non-exclusive entry is rejected. 481*84c42f51SDaniel Borkmann 482*84c42f51SDaniel Borkmann``BPF_MAP_CREATE`` (``union bpf_attr``): 483*84c42f51SDaniel Borkmann 484*84c42f51SDaniel Borkmann``excl_prog_hash``, ``excl_prog_hash_size`` 485*84c42f51SDaniel Borkmann SHA-256 digest of the program permitted to access this (exclusive) map. This 486*84c42f51SDaniel Borkmann binds the metadata map to the loader; it is not a hash of the map *content*. 487*84c42f51SDaniel Borkmann The map content is not hashed separately at all - it is covered, as bytes, 488*84c42f51SDaniel Borkmann by the program signature. 489*84c42f51SDaniel Borkmann 490*84c42f51SDaniel BorkmannNotes and limitations 491*84c42f51SDaniel Borkmann====================== 492*84c42f51SDaniel Borkmann 493*84c42f51SDaniel Borkmann- The instructions plus folded metadata are verified as one ``bpf_dynptr``, 494*84c42f51SDaniel Borkmann which bounds the combined size (currently ~16 MiB); very large objects can 495*84c42f51SDaniel Borkmann exceed it. 496*84c42f51SDaniel Borkmann- The metadata container is a single-element array map, accessed through 497*84c42f51SDaniel Borkmann ``map_direct_value_addr``. 498