tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 16931859a6500d360b90aeacab3b505a3560a3ed commit: 66e3a13e7c2c44d0c9dd6bb244680ca7529a8845 bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr date: 6 months ago config: x86_64-randconfig-x012-20230816 compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0 reproduce: If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202308181001.WHfr3aLI-lkp@intel.com/ All warnings (new ones prefixed by >>): kernel/bpf/helpers.c:1874:19: warning: no previous declaration for 'bpf_obj_new_impl' [-Wmissing-declarations] __bpf_kfunc void *bpf_obj_new_impl(u64 local_type_id__k, void *meta__ign) ^~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1888:18: warning: no previous declaration for 'bpf_obj_drop_impl' [-Wmissing-declarations] __bpf_kfunc void bpf_obj_drop_impl(void *p__alloc, void *meta__ign) ^~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1909:18: warning: no previous declaration for 'bpf_list_push_front' [-Wmissing-declarations] __bpf_kfunc void bpf_list_push_front(struct bpf_list_head *head, struct bpf_list_node *node) ^~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1914:18: warning: no previous declaration for 'bpf_list_push_back' [-Wmissing-declarations] __bpf_kfunc void bpf_list_push_back(struct bpf_list_head *head, struct bpf_list_node *node) ^~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1932:35: warning: no previous declaration for 'bpf_list_pop_front' [-Wmissing-declarations] __bpf_kfunc struct bpf_list_node *bpf_list_pop_front(struct bpf_list_head *head) ^~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1937:35: warning: no previous declaration for 'bpf_list_pop_back' [-Wmissing-declarations] __bpf_kfunc struct bpf_list_node *bpf_list_pop_back(struct bpf_list_head *head) ^~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1942:33: warning: no previous declaration for 'bpf_rbtree_remove' [-Wmissing-declarations] __bpf_kfunc struct bpf_rb_node *bpf_rbtree_remove(struct bpf_rb_root *root, ^~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1979:18: warning: no previous declaration for 'bpf_rbtree_add' [-Wmissing-declarations] __bpf_kfunc void bpf_rbtree_add(struct bpf_rb_root *root, struct bpf_rb_node *node, ^~~~~~~~~~~~~~ kernel/bpf/helpers.c:1985:33: warning: no previous declaration for 'bpf_rbtree_first' [-Wmissing-declarations] __bpf_kfunc struct bpf_rb_node *bpf_rbtree_first(struct bpf_rb_root *root) ^~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:1998:33: warning: no previous declaration for 'bpf_task_acquire' [-Wmissing-declarations] __bpf_kfunc struct task_struct *bpf_task_acquire(struct task_struct *p) ^~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2009:33: warning: no previous declaration for 'bpf_task_acquire_not_zero' [-Wmissing-declarations] __bpf_kfunc struct task_struct *bpf_task_acquire_not_zero(struct task_struct *p) ^~~~~~~~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2061:33: warning: no previous declaration for 'bpf_task_kptr_get' [-Wmissing-declarations] __bpf_kfunc struct task_struct *bpf_task_kptr_get(struct task_struct **pp) ^~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2074:18: warning: no previous declaration for 'bpf_task_release' [-Wmissing-declarations] __bpf_kfunc void bpf_task_release(struct task_struct *p) ^~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2089:28: warning: no previous declaration for 'bpf_cgroup_acquire' [-Wmissing-declarations] __bpf_kfunc struct cgroup *bpf_cgroup_acquire(struct cgroup *cgrp) ^~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2101:28: warning: no previous declaration for 'bpf_cgroup_kptr_get' [-Wmissing-declarations] __bpf_kfunc struct cgroup *bpf_cgroup_kptr_get(struct cgroup **cgrpp) ^~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2133:18: warning: no previous declaration for 'bpf_cgroup_release' [-Wmissing-declarations] __bpf_kfunc void bpf_cgroup_release(struct cgroup *cgrp) ^~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2148:28: warning: no previous declaration for 'bpf_cgroup_ancestor' [-Wmissing-declarations] __bpf_kfunc struct cgroup *bpf_cgroup_ancestor(struct cgroup *cgrp, int level) ^~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2166:28: warning: no previous declaration for 'bpf_cgroup_from_id' [-Wmissing-declarations] __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid) ^~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2183:33: warning: no previous declaration for 'bpf_task_from_pid' [-Wmissing-declarations] __bpf_kfunc struct task_struct *bpf_task_from_pid(s32 pid) ^~~~~~~~~~~~~~~~~ >> kernel/bpf/helpers.c:2223:19: warning: no previous declaration for 'bpf_dynptr_slice' [-Wmissing-declarations] __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset, ^~~~~~~~~~~~~~~~ >> kernel/bpf/helpers.c:2301:19: warning: no previous declaration for 'bpf_dynptr_slice_rdwr' [-Wmissing-declarations] __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, ^~~~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2332:19: warning: no previous declaration for 'bpf_cast_to_kern_ctx' [-Wmissing-declarations] __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) ^~~~~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2337:19: warning: no previous declaration for 'bpf_rdonly_cast' [-Wmissing-declarations] __bpf_kfunc void *bpf_rdonly_cast(void *obj__ign, u32 btf_id__k) ^~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2342:18: warning: no previous declaration for 'bpf_rcu_read_lock' [-Wmissing-declarations] __bpf_kfunc void bpf_rcu_read_lock(void) ^~~~~~~~~~~~~~~~~ kernel/bpf/helpers.c:2347:18: warning: no previous declaration for 'bpf_rcu_read_unlock' [-Wmissing-declarations] __bpf_kfunc void bpf_rcu_read_unlock(void) ^~~~~~~~~~~~~~~~~~~ vim +/bpf_dynptr_slice +2223 kernel/bpf/helpers.c 2195 2196 /** 2197 * bpf_dynptr_slice - Obtain a read-only pointer to the dynptr data. 2198 * 2199 * For non-skb and non-xdp type dynptrs, there is no difference between 2200 * bpf_dynptr_slice and bpf_dynptr_data. 2201 * 2202 * If the intention is to write to the data slice, please use 2203 * bpf_dynptr_slice_rdwr. 2204 * 2205 * The user must check that the returned pointer is not null before using it. 2206 * 2207 * Please note that in the case of skb and xdp dynptrs, bpf_dynptr_slice 2208 * does not change the underlying packet data pointers, so a call to 2209 * bpf_dynptr_slice will not invalidate any ctx->data/data_end pointers in 2210 * the bpf program. 2211 * 2212 * @ptr: The dynptr whose data slice to retrieve 2213 * @offset: Offset into the dynptr 2214 * @buffer: User-provided buffer to copy contents into 2215 * @buffer__szk: Size (in bytes) of the buffer. This is the length of the 2216 * requested slice. This must be a constant. 2217 * 2218 * @returns: NULL if the call failed (eg invalid dynptr), pointer to a read-only 2219 * data slice (can be either direct pointer to the data or a pointer to the user 2220 * provided buffer, with its contents containing the data, if unable to obtain 2221 * direct pointer) 2222 */ > 2223 __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset, 2224 void *buffer, u32 buffer__szk) 2225 { 2226 enum bpf_dynptr_type type; 2227 u32 len = buffer__szk; 2228 int err; 2229 2230 if (!ptr->data) 2231 return 0; 2232 2233 err = bpf_dynptr_check_off_len(ptr, offset, len); 2234 if (err) 2235 return 0; 2236 2237 type = bpf_dynptr_get_type(ptr); 2238 2239 switch (type) { 2240 case BPF_DYNPTR_TYPE_LOCAL: 2241 case BPF_DYNPTR_TYPE_RINGBUF: 2242 return ptr->data + ptr->offset + offset; 2243 case BPF_DYNPTR_TYPE_SKB: 2244 return skb_header_pointer(ptr->data, ptr->offset + offset, len, buffer); 2245 case BPF_DYNPTR_TYPE_XDP: 2246 { 2247 void *xdp_ptr = bpf_xdp_pointer(ptr->data, ptr->offset + offset, len); 2248 if (xdp_ptr) 2249 return xdp_ptr; 2250 2251 bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer, len, false); 2252 return buffer; 2253 } 2254 default: 2255 WARN_ONCE(true, "unknown dynptr type %d\n", type); 2256 return 0; 2257 } 2258 } 2259 2260 /** 2261 * bpf_dynptr_slice_rdwr - Obtain a writable pointer to the dynptr data. 2262 * 2263 * For non-skb and non-xdp type dynptrs, there is no difference between 2264 * bpf_dynptr_slice and bpf_dynptr_data. 2265 * 2266 * The returned pointer is writable and may point to either directly the dynptr 2267 * data at the requested offset or to the buffer if unable to obtain a direct 2268 * data pointer to (example: the requested slice is to the paged area of an skb 2269 * packet). In the case where the returned pointer is to the buffer, the user 2270 * is responsible for persisting writes through calling bpf_dynptr_write(). This 2271 * usually looks something like this pattern: 2272 * 2273 * struct eth_hdr *eth = bpf_dynptr_slice_rdwr(&dynptr, 0, buffer, sizeof(buffer)); 2274 * if (!eth) 2275 * return TC_ACT_SHOT; 2276 * 2277 * // mutate eth header // 2278 * 2279 * if (eth == buffer) 2280 * bpf_dynptr_write(&ptr, 0, buffer, sizeof(buffer), 0); 2281 * 2282 * Please note that, as in the example above, the user must check that the 2283 * returned pointer is not null before using it. 2284 * 2285 * Please also note that in the case of skb and xdp dynptrs, bpf_dynptr_slice_rdwr 2286 * does not change the underlying packet data pointers, so a call to 2287 * bpf_dynptr_slice_rdwr will not invalidate any ctx->data/data_end pointers in 2288 * the bpf program. 2289 * 2290 * @ptr: The dynptr whose data slice to retrieve 2291 * @offset: Offset into the dynptr 2292 * @buffer: User-provided buffer to copy contents into 2293 * @buffer__szk: Size (in bytes) of the buffer. This is the length of the 2294 * requested slice. This must be a constant. 2295 * 2296 * @returns: NULL if the call failed (eg invalid dynptr), pointer to a 2297 * data slice (can be either direct pointer to the data or a pointer to the user 2298 * provided buffer, with its contents containing the data, if unable to obtain 2299 * direct pointer) 2300 */ > 2301 __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, 2302 void *buffer, u32 buffer__szk) 2303 { 2304 if (!ptr->data || bpf_dynptr_is_rdonly(ptr)) 2305 return 0; 2306 2307 /* bpf_dynptr_slice_rdwr is the same logic as bpf_dynptr_slice. 2308 * 2309 * For skb-type dynptrs, it is safe to write into the returned pointer 2310 * if the bpf program allows skb data writes. There are two possiblities 2311 * that may occur when calling bpf_dynptr_slice_rdwr: 2312 * 2313 * 1) The requested slice is in the head of the skb. In this case, the 2314 * returned pointer is directly to skb data, and if the skb is cloned, the 2315 * verifier will have uncloned it (see bpf_unclone_prologue()) already. 2316 * The pointer can be directly written into. 2317 * 2318 * 2) Some portion of the requested slice is in the paged buffer area. 2319 * In this case, the requested data will be copied out into the buffer 2320 * and the returned pointer will be a pointer to the buffer. The skb 2321 * will not be pulled. To persist the write, the user will need to call 2322 * bpf_dynptr_write(), which will pull the skb and commit the write. 2323 * 2324 * Similarly for xdp programs, if the requested slice is not across xdp 2325 * fragments, then a direct pointer will be returned, otherwise the data 2326 * will be copied out into the buffer and the user will need to call 2327 * bpf_dynptr_write() to commit changes. 2328 */ 2329 return bpf_dynptr_slice(ptr, offset, buffer, buffer__szk); 2330 } 2331 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki