Back to home page

OSCL-LXR

 
 

    


0001 =============================
0002 BPF Kernel Functions (kfuncs)
0003 =============================
0004 
0005 1. Introduction
0006 ===============
0007 
0008 BPF Kernel Functions or more commonly known as kfuncs are functions in the Linux
0009 kernel which are exposed for use by BPF programs. Unlike normal BPF helpers,
0010 kfuncs do not have a stable interface and can change from one kernel release to
0011 another. Hence, BPF programs need to be updated in response to changes in the
0012 kernel.
0013 
0014 2. Defining a kfunc
0015 ===================
0016 
0017 There are two ways to expose a kernel function to BPF programs, either make an
0018 existing function in the kernel visible, or add a new wrapper for BPF. In both
0019 cases, care must be taken that BPF program can only call such function in a
0020 valid context. To enforce this, visibility of a kfunc can be per program type.
0021 
0022 If you are not creating a BPF wrapper for existing kernel function, skip ahead
0023 to :ref:`BPF_kfunc_nodef`.
0024 
0025 2.1 Creating a wrapper kfunc
0026 ----------------------------
0027 
0028 When defining a wrapper kfunc, the wrapper function should have extern linkage.
0029 This prevents the compiler from optimizing away dead code, as this wrapper kfunc
0030 is not invoked anywhere in the kernel itself. It is not necessary to provide a
0031 prototype in a header for the wrapper kfunc.
0032 
0033 An example is given below::
0034 
0035         /* Disables missing prototype warnings */
0036         __diag_push();
0037         __diag_ignore_all("-Wmissing-prototypes",
0038                           "Global kfuncs as their definitions will be in BTF");
0039 
0040         struct task_struct *bpf_find_get_task_by_vpid(pid_t nr)
0041         {
0042                 return find_get_task_by_vpid(nr);
0043         }
0044 
0045         __diag_pop();
0046 
0047 A wrapper kfunc is often needed when we need to annotate parameters of the
0048 kfunc. Otherwise one may directly make the kfunc visible to the BPF program by
0049 registering it with the BPF subsystem. See :ref:`BPF_kfunc_nodef`.
0050 
0051 2.2 Annotating kfunc parameters
0052 -------------------------------
0053 
0054 Similar to BPF helpers, there is sometime need for additional context required
0055 by the verifier to make the usage of kernel functions safer and more useful.
0056 Hence, we can annotate a parameter by suffixing the name of the argument of the
0057 kfunc with a __tag, where tag may be one of the supported annotations.
0058 
0059 2.2.1 __sz Annotation
0060 ---------------------
0061 
0062 This annotation is used to indicate a memory and size pair in the argument list.
0063 An example is given below::
0064 
0065         void bpf_memzero(void *mem, int mem__sz)
0066         {
0067         ...
0068         }
0069 
0070 Here, the verifier will treat first argument as a PTR_TO_MEM, and second
0071 argument as its size. By default, without __sz annotation, the size of the type
0072 of the pointer is used. Without __sz annotation, a kfunc cannot accept a void
0073 pointer.
0074 
0075 .. _BPF_kfunc_nodef:
0076 
0077 2.3 Using an existing kernel function
0078 -------------------------------------
0079 
0080 When an existing function in the kernel is fit for consumption by BPF programs,
0081 it can be directly registered with the BPF subsystem. However, care must still
0082 be taken to review the context in which it will be invoked by the BPF program
0083 and whether it is safe to do so.
0084 
0085 2.4 Annotating kfuncs
0086 ---------------------
0087 
0088 In addition to kfuncs' arguments, verifier may need more information about the
0089 type of kfunc(s) being registered with the BPF subsystem. To do so, we define
0090 flags on a set of kfuncs as follows::
0091 
0092         BTF_SET8_START(bpf_task_set)
0093         BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL)
0094         BTF_ID_FLAGS(func, bpf_put_pid, KF_RELEASE)
0095         BTF_SET8_END(bpf_task_set)
0096 
0097 This set encodes the BTF ID of each kfunc listed above, and encodes the flags
0098 along with it. Ofcourse, it is also allowed to specify no flags.
0099 
0100 2.4.1 KF_ACQUIRE flag
0101 ---------------------
0102 
0103 The KF_ACQUIRE flag is used to indicate that the kfunc returns a pointer to a
0104 refcounted object. The verifier will then ensure that the pointer to the object
0105 is eventually released using a release kfunc, or transferred to a map using a
0106 referenced kptr (by invoking bpf_kptr_xchg). If not, the verifier fails the
0107 loading of the BPF program until no lingering references remain in all possible
0108 explored states of the program.
0109 
0110 2.4.2 KF_RET_NULL flag
0111 ----------------------
0112 
0113 The KF_RET_NULL flag is used to indicate that the pointer returned by the kfunc
0114 may be NULL. Hence, it forces the user to do a NULL check on the pointer
0115 returned from the kfunc before making use of it (dereferencing or passing to
0116 another helper). This flag is often used in pairing with KF_ACQUIRE flag, but
0117 both are orthogonal to each other.
0118 
0119 2.4.3 KF_RELEASE flag
0120 ---------------------
0121 
0122 The KF_RELEASE flag is used to indicate that the kfunc releases the pointer
0123 passed in to it. There can be only one referenced pointer that can be passed in.
0124 All copies of the pointer being released are invalidated as a result of invoking
0125 kfunc with this flag.
0126 
0127 2.4.4 KF_KPTR_GET flag
0128 ----------------------
0129 
0130 The KF_KPTR_GET flag is used to indicate that the kfunc takes the first argument
0131 as a pointer to kptr, safely increments the refcount of the object it points to,
0132 and returns a reference to the user. The rest of the arguments may be normal
0133 arguments of a kfunc. The KF_KPTR_GET flag should be used in conjunction with
0134 KF_ACQUIRE and KF_RET_NULL flags.
0135 
0136 2.4.5 KF_TRUSTED_ARGS flag
0137 --------------------------
0138 
0139 The KF_TRUSTED_ARGS flag is used for kfuncs taking pointer arguments. It
0140 indicates that the all pointer arguments will always be refcounted, and have
0141 their offset set to 0. It can be used to enforce that a pointer to a refcounted
0142 object acquired from a kfunc or BPF helper is passed as an argument to this
0143 kfunc without any modifications (e.g. pointer arithmetic) such that it is
0144 trusted and points to the original object. This flag is often used for kfuncs
0145 that operate (change some property, perform some operation) on an object that
0146 was obtained using an acquire kfunc. Such kfuncs need an unchanged pointer to
0147 ensure the integrity of the operation being performed on the expected object.
0148 
0149 2.5 Registering the kfuncs
0150 --------------------------
0151 
0152 Once the kfunc is prepared for use, the final step to making it visible is
0153 registering it with the BPF subsystem. Registration is done per BPF program
0154 type. An example is shown below::
0155 
0156         BTF_SET8_START(bpf_task_set)
0157         BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL)
0158         BTF_ID_FLAGS(func, bpf_put_pid, KF_RELEASE)
0159         BTF_SET8_END(bpf_task_set)
0160 
0161         static const struct btf_kfunc_id_set bpf_task_kfunc_set = {
0162                 .owner = THIS_MODULE,
0163                 .set   = &bpf_task_set,
0164         };
0165 
0166         static int init_subsystem(void)
0167         {
0168                 return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_task_kfunc_set);
0169         }
0170         late_initcall(init_subsystem);