> Historically binfmt_misc has only matched binaries by magic bytes or file > extension, and always redirects a match to a fixed interpreter recorded in > the registration. This is insufficient when the match requires parsing the > binary header (e.g. inspecting ELF program headers) or when the interpreter > must be computed per-binary rather than hard-coded. > > Introduce a new 'B' (BPF) handler type. A pinned SOCKET_FILTER program is > registered in place of the magic/mask, and no interpreter is recorded: > > echo ':name:B:<bpf_pinned_path>::::<flags>' \ > > /proc/sys/fs/binfmt_misc/register > > When a binary is executed, binfmt_misc runs the program with the > BINPRM_BUF_SIZE file-header buffer as context. Returning 1 selects the > handler; returning 0 falls through to the remaining handlers. > > Unlike magic/extension handlers, a 'B' handler carries no interpreter of its > own: the program chooses it via a new helper, bpf_binprm_set_interp(). This > lets the program compute the interpreter path however it sees fit (for example > relative to the binary). A 'B' handler is therefore a strict superset of the > existing magic handlers -- any of them can be expressed as a program that > matches on the header and sets a fixed interpreter. > > bpf_binprm_set_interp() is exposed to SOCKET_FILTER programs and stashes the > chosen path on a per-CPU area that binfmt_misc reads back immediately after > the run under migrate_disable(); only a match that set an interpreter > allocates. > > Signed-off-by: Farid Zakaria <[email protected]>
Ignoring the blatant bpf abuse here I think this is quite workable. So this can be turned into an actual design and patch imho... Note that binfmt_misc is namespaced and can be mounted inside of user namespace + mount namespaces fwiw. So a container mounting binfmt_misc (a fresh instance - few do) would escape that bpf program. On the other hand it would allow to register a custom bpf program per container if needed... -- Christian Brauner <[email protected]>

