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