| 1 |
|
| 2 | #ifndef _LINUX_BINFMT_MISC_H
|
| 3 | #define _LINUX_BINFMT_MISC_H
|
| 4 |
|
| 5 | #include <linux/types.h>
|
| 6 |
|
| 7 | struct bpf_prog;
|
| 8 | struct file;
|
| 9 | struct linux_binprm;
|
| 10 | struct ucounts;
|
| 11 | struct user_namespace;
|
| 12 |
|
| 13 | #define BINFMT_MISC_OPS_NAME_MAX 16
|
| 14 |
|
| 15 |
|
| 16 | #define BINFMT_MISC_INTERP_NAME_MAX 32
|
| 17 |
|
| 18 |
|
| 19 | #define BINFMT_MISC_INTERP_MAX 100
|
| 20 |
|
| 21 | |
| 22 | * struct binfmt_misc_interp - an interpreter an entry was registered with
|
| 23 | * @list: link in the entry's list, in registration order
|
| 24 | * @file: the file, opened at registration and never resolved again
|
| 25 | * @ucounts: the UCOUNT_BINFMT_MISC_INTERPRETERS charge the binding took
|
| 26 | * @path: the path it was registered under, used as the name the interpreter
|
| 27 | * runs under; stored after @name in the same allocation
|
| 28 | * @name: the name the load program selects it by; empty for the fixed
|
| 29 | * interpreter of a static 'F' entry
|
| 30 | *
|
| 31 | * Owned by the entry and living exactly as long as it does. The list head
|
| 32 | * is handed to the handler's load program for the duration of one exec,
|
| 33 | * which picks one with bpf_binprm_select_interp().
|
| 34 |
|
| 35 | struct binfmt_misc_interp {
|
| 36 | struct list_head list;
|
| 37 | struct file *file;
|
| 38 | struct ucounts *ucounts;
|
| 39 | const char *path;
|
| 40 | char name[];
|
| 41 | };
|
| 42 |
|
| 43 | const struct binfmt_misc_interp *
|
| 44 | binfmt_misc_find_interp(const struct list_head *interps, const char *name);
|
| 45 |
|
| 46 | |
| 47 | * enum bpf_binprm_flags - per-exec invocation flags a load program can request
|
| 48 | * @BPF_BINPRM_PRESERVE_ARGV0: keep the caller's argv[0] (like the 'P' flag)
|
| 49 | * @BPF_BINPRM_CREDENTIALS: compute credentials from the binary; implies execfd
|
| 50 | * (like the 'C' flag)
|
| 51 | * @BPF_BINPRM_EXECFD: pass the binary via AT_EXECFD (like the 'O' flag)
|
| 52 | * @BPF_BINPRM_TRANSPARENT: leave argv untouched, the interpreter takes the
|
| 53 | * binary from AT_EXECFD (like the 'T' flag); implies
|
| 54 | * execfd, excludes preserve-argv0
|
| 55 | * @BPF_BINPRM_LOADER: substitute the interpreter for the binary's PT_INTERP
|
| 56 | * and run the binary as a native exec (like the 'L'
|
| 57 | * flag); excludes every other flag
|
| 58 | *
|
| 59 | * Set from a load program with bpf_binprm_set_flags(). Unlike a static entry,
|
| 60 | * a bpf handler chooses these per exec rather than once at registration.
|
| 61 |
|
| 62 | enum bpf_binprm_flags {
|
| 63 | BPF_BINPRM_PRESERVE_ARGV0 = (1ULL << 0),
|
| 64 | BPF_BINPRM_CREDENTIALS = (1ULL << 1),
|
| 65 | BPF_BINPRM_EXECFD = (1ULL << 2),
|
| 66 | BPF_BINPRM_TRANSPARENT = (1ULL << 3),
|
| 67 | BPF_BINPRM_LOADER = (1ULL << 4),
|
| 68 | };
|
| 69 |
|
| 70 | |
| 71 | * struct binfmt_misc_ops - bpf-backed binary type handler
|
| 72 | * @match: decide whether the handler applies to @bprm; consulted from the
|
| 73 | * entry lookup walk like static magic and extension matching, in
|
| 74 | * registration order with first-match-wins semantics; sleepable,
|
| 75 | * so it can read the binary to decide, but the verifier rejects
|
| 76 | * the interpreter selection kfuncs in it
|
| 77 | * @load: select an interpreter for the matched @bprm via
|
| 78 | * bpf_binprm_set_interp(), or one the entry bound via
|
| 79 | * bpf_binprm_select_interp(), and return zero; a match is
|
| 80 | * committed, so a failure fails the exec instead of falling
|
| 81 | * through to later entries; -ENOEXEC does not fail the exec but
|
| 82 | * moves on to the remaining binary formats
|
| 83 | * @name: name that 'B' entries reference the handler by
|
| 84 |
|
| 85 | struct binfmt_misc_ops {
|
| 86 | bool (*match)(struct linux_binprm *bprm);
|
| 87 | int (*load)(struct linux_binprm *bprm);
|
| 88 | char name[BINFMT_MISC_OPS_NAME_MAX];
|
| 89 | };
|
| 90 |
|
| 91 | #ifdef CONFIG_BINFMT_MISC_BPF
|
| 92 | const struct binfmt_misc_ops *binfmt_misc_get_ops(struct user_namespace *user_ns,
|
| 93 | const char *name);
|
| 94 | void binfmt_misc_put_ops(const struct binfmt_misc_ops *ops);
|
| 95 | bool bpf_prog_is_binfmt_misc_ops(const struct bpf_prog *prog);
|
| 96 | #else
|
| 97 | static inline const struct binfmt_misc_ops *
|
| 98 | binfmt_misc_get_ops(struct user_namespace *user_ns, const char *name)
|
| 99 | {
|
| 100 | return NULL;
|
| 101 | }
|
| 102 |
|
| 103 | static inline void binfmt_misc_put_ops(const struct binfmt_misc_ops *ops)
|
| 104 | {
|
| 105 | }
|
| 106 |
|
| 107 | static inline bool bpf_prog_is_binfmt_misc_ops(const struct bpf_prog *prog)
|
| 108 | {
|
| 109 | return false;
|
| 110 | }
|
| 111 | #endif
|
| 112 |
|
| 113 | #endif
|