Message ID | 677377439845fcb9135151d1dac1102ed3d6c924.1717881178.git.dxu@dxuuu.xyz (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | bpf: Support dumping kfunc prototypes from BTF | expand |
Hi Daniel, kernel test robot noticed the following build warnings: [auto build test WARNING on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Xu/kbuild-bpf-Tell-pahole-to-DECL_TAG-kfuncs/20240609-052326 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/677377439845fcb9135151d1dac1102ed3d6c924.1717881178.git.dxu%40dxuuu.xyz patch subject: [PATCH bpf-next v4 09/12] bpf: treewide: Align kfunc signatures to prog point-of-view config: riscv-defconfig (https://download.01.org/0day-ci/archive/20240609/202406090852.FB1i4svo-lkp@intel.com/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project d7d2d4f53fc79b4b58e8d8d08151b577c3699d4a) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240609/202406090852.FB1i4svo-lkp@intel.com/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 <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202406090852.FB1i4svo-lkp@intel.com/ All warnings (new ones prefixed by >>): >> kernel/bpf/helpers.c:2464: warning: Function parameter or struct member 'p' not described in 'bpf_dynptr_slice' >> kernel/bpf/helpers.c:2464: warning: Excess function parameter 'ptr' description in 'bpf_dynptr_slice' >> kernel/bpf/helpers.c:2549: warning: Function parameter or struct member 'p' not described in 'bpf_dynptr_slice_rdwr' >> kernel/bpf/helpers.c:2549: warning: Excess function parameter 'ptr' description in 'bpf_dynptr_slice_rdwr' vim +2464 kernel/bpf/helpers.c 3f0e6f2b41d35d David Vernet 2022-11-22 2433 66e3a13e7c2c44 Joanne Koong 2023-03-01 2434 /** 7ce60b110eece1 David Vernet 2023-03-01 2435 * bpf_dynptr_slice() - Obtain a read-only pointer to the dynptr data. 7ce60b110eece1 David Vernet 2023-03-01 2436 * @ptr: The dynptr whose data slice to retrieve 7ce60b110eece1 David Vernet 2023-03-01 2437 * @offset: Offset into the dynptr 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2438 * @buffer__opt: User-provided buffer to copy contents into. May be NULL 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2439 * @buffer__szk: Size (in bytes) of the buffer if present. This is the 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2440 * length of the requested slice. This must be a constant. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2441 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2442 * For non-skb and non-xdp type dynptrs, there is no difference between 66e3a13e7c2c44 Joanne Koong 2023-03-01 2443 * bpf_dynptr_slice and bpf_dynptr_data. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2444 * 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2445 * If buffer__opt is NULL, the call will fail if buffer_opt was needed. 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2446 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2447 * If the intention is to write to the data slice, please use 66e3a13e7c2c44 Joanne Koong 2023-03-01 2448 * bpf_dynptr_slice_rdwr. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2449 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2450 * The user must check that the returned pointer is not null before using it. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2451 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2452 * Please note that in the case of skb and xdp dynptrs, bpf_dynptr_slice 66e3a13e7c2c44 Joanne Koong 2023-03-01 2453 * does not change the underlying packet data pointers, so a call to 66e3a13e7c2c44 Joanne Koong 2023-03-01 2454 * bpf_dynptr_slice will not invalidate any ctx->data/data_end pointers in 66e3a13e7c2c44 Joanne Koong 2023-03-01 2455 * the bpf program. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2456 * 7ce60b110eece1 David Vernet 2023-03-01 2457 * Return: NULL if the call failed (eg invalid dynptr), pointer to a read-only 66e3a13e7c2c44 Joanne Koong 2023-03-01 2458 * data slice (can be either direct pointer to the data or a pointer to the user 66e3a13e7c2c44 Joanne Koong 2023-03-01 2459 * provided buffer, with its contents containing the data, if unable to obtain 66e3a13e7c2c44 Joanne Koong 2023-03-01 2460 * direct pointer) 66e3a13e7c2c44 Joanne Koong 2023-03-01 2461 */ ec3b75c0e6eb53 Daniel Xu 2024-06-08 2462 __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset, 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2463 void *buffer__opt, u32 buffer__szk) 66e3a13e7c2c44 Joanne Koong 2023-03-01 @2464 { ec3b75c0e6eb53 Daniel Xu 2024-06-08 2465 const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2466 enum bpf_dynptr_type type; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2467 u32 len = buffer__szk; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2468 int err; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2469 66e3a13e7c2c44 Joanne Koong 2023-03-01 2470 if (!ptr->data) c45eac537bd8b4 Joanne Koong 2023-03-01 2471 return NULL; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2472 66e3a13e7c2c44 Joanne Koong 2023-03-01 2473 err = bpf_dynptr_check_off_len(ptr, offset, len); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2474 if (err) c45eac537bd8b4 Joanne Koong 2023-03-01 2475 return NULL; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2476 66e3a13e7c2c44 Joanne Koong 2023-03-01 2477 type = bpf_dynptr_get_type(ptr); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2478 66e3a13e7c2c44 Joanne Koong 2023-03-01 2479 switch (type) { 66e3a13e7c2c44 Joanne Koong 2023-03-01 2480 case BPF_DYNPTR_TYPE_LOCAL: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2481 case BPF_DYNPTR_TYPE_RINGBUF: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2482 return ptr->data + ptr->offset + offset; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2483 case BPF_DYNPTR_TYPE_SKB: 6f5a630d7c57cd Alexei Starovoitov 2023-07-18 2484 if (buffer__opt) 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2485 return skb_header_pointer(ptr->data, ptr->offset + offset, len, buffer__opt); 6f5a630d7c57cd Alexei Starovoitov 2023-07-18 2486 else 6f5a630d7c57cd Alexei Starovoitov 2023-07-18 2487 return skb_pointer_if_linear(ptr->data, ptr->offset + offset, len); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2488 case BPF_DYNPTR_TYPE_XDP: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2489 { 66e3a13e7c2c44 Joanne Koong 2023-03-01 2490 void *xdp_ptr = bpf_xdp_pointer(ptr->data, ptr->offset + offset, len); 5426700e6841bf Kui-Feng Lee 2023-08-03 2491 if (!IS_ERR_OR_NULL(xdp_ptr)) 66e3a13e7c2c44 Joanne Koong 2023-03-01 2492 return xdp_ptr; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2493 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2494 if (!buffer__opt) 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2495 return NULL; 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2496 bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer__opt, len, false); 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2497 return buffer__opt; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2498 } 66e3a13e7c2c44 Joanne Koong 2023-03-01 2499 default: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2500 WARN_ONCE(true, "unknown dynptr type %d\n", type); c45eac537bd8b4 Joanne Koong 2023-03-01 2501 return NULL; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2502 } 66e3a13e7c2c44 Joanne Koong 2023-03-01 2503 } 66e3a13e7c2c44 Joanne Koong 2023-03-01 2504 66e3a13e7c2c44 Joanne Koong 2023-03-01 2505 /** 7ce60b110eece1 David Vernet 2023-03-01 2506 * bpf_dynptr_slice_rdwr() - Obtain a writable pointer to the dynptr data. 7ce60b110eece1 David Vernet 2023-03-01 2507 * @ptr: The dynptr whose data slice to retrieve 7ce60b110eece1 David Vernet 2023-03-01 2508 * @offset: Offset into the dynptr 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2509 * @buffer__opt: User-provided buffer to copy contents into. May be NULL 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2510 * @buffer__szk: Size (in bytes) of the buffer if present. This is the 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2511 * length of the requested slice. This must be a constant. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2512 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2513 * For non-skb and non-xdp type dynptrs, there is no difference between 66e3a13e7c2c44 Joanne Koong 2023-03-01 2514 * bpf_dynptr_slice and bpf_dynptr_data. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2515 * 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2516 * If buffer__opt is NULL, the call will fail if buffer_opt was needed. 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2517 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2518 * The returned pointer is writable and may point to either directly the dynptr 66e3a13e7c2c44 Joanne Koong 2023-03-01 2519 * data at the requested offset or to the buffer if unable to obtain a direct 66e3a13e7c2c44 Joanne Koong 2023-03-01 2520 * data pointer to (example: the requested slice is to the paged area of an skb 66e3a13e7c2c44 Joanne Koong 2023-03-01 2521 * packet). In the case where the returned pointer is to the buffer, the user 66e3a13e7c2c44 Joanne Koong 2023-03-01 2522 * is responsible for persisting writes through calling bpf_dynptr_write(). This 66e3a13e7c2c44 Joanne Koong 2023-03-01 2523 * usually looks something like this pattern: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2524 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2525 * struct eth_hdr *eth = bpf_dynptr_slice_rdwr(&dynptr, 0, buffer, sizeof(buffer)); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2526 * if (!eth) 66e3a13e7c2c44 Joanne Koong 2023-03-01 2527 * return TC_ACT_SHOT; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2528 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2529 * // mutate eth header // 66e3a13e7c2c44 Joanne Koong 2023-03-01 2530 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2531 * if (eth == buffer) 66e3a13e7c2c44 Joanne Koong 2023-03-01 2532 * bpf_dynptr_write(&ptr, 0, buffer, sizeof(buffer), 0); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2533 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2534 * Please note that, as in the example above, the user must check that the 66e3a13e7c2c44 Joanne Koong 2023-03-01 2535 * returned pointer is not null before using it. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2536 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2537 * Please also note that in the case of skb and xdp dynptrs, bpf_dynptr_slice_rdwr 66e3a13e7c2c44 Joanne Koong 2023-03-01 2538 * does not change the underlying packet data pointers, so a call to 66e3a13e7c2c44 Joanne Koong 2023-03-01 2539 * bpf_dynptr_slice_rdwr will not invalidate any ctx->data/data_end pointers in 66e3a13e7c2c44 Joanne Koong 2023-03-01 2540 * the bpf program. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2541 * 7ce60b110eece1 David Vernet 2023-03-01 2542 * Return: NULL if the call failed (eg invalid dynptr), pointer to a 66e3a13e7c2c44 Joanne Koong 2023-03-01 2543 * data slice (can be either direct pointer to the data or a pointer to the user 66e3a13e7c2c44 Joanne Koong 2023-03-01 2544 * provided buffer, with its contents containing the data, if unable to obtain 66e3a13e7c2c44 Joanne Koong 2023-03-01 2545 * direct pointer) 66e3a13e7c2c44 Joanne Koong 2023-03-01 2546 */ ec3b75c0e6eb53 Daniel Xu 2024-06-08 2547 __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u32 offset, 3bda08b63670c3 Daniel Rosenberg 2023-05-05 2548 void *buffer__opt, u32 buffer__szk) 66e3a13e7c2c44 Joanne Koong 2023-03-01 @2549 { ec3b75c0e6eb53 Daniel Xu 2024-06-08 2550 const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; ec3b75c0e6eb53 Daniel Xu 2024-06-08 2551 540ccf96ddbc17 Joanne Koong 2023-04-20 2552 if (!ptr->data || __bpf_dynptr_is_rdonly(ptr)) c45eac537bd8b4 Joanne Koong 2023-03-01 2553 return NULL; 66e3a13e7c2c44 Joanne Koong 2023-03-01 2554 66e3a13e7c2c44 Joanne Koong 2023-03-01 2555 /* bpf_dynptr_slice_rdwr is the same logic as bpf_dynptr_slice. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2556 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2557 * For skb-type dynptrs, it is safe to write into the returned pointer a7de265cb2d849 Rafael Passos 2024-04-17 2558 * if the bpf program allows skb data writes. There are two possibilities 66e3a13e7c2c44 Joanne Koong 2023-03-01 2559 * that may occur when calling bpf_dynptr_slice_rdwr: 66e3a13e7c2c44 Joanne Koong 2023-03-01 2560 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2561 * 1) The requested slice is in the head of the skb. In this case, the 66e3a13e7c2c44 Joanne Koong 2023-03-01 2562 * returned pointer is directly to skb data, and if the skb is cloned, the 66e3a13e7c2c44 Joanne Koong 2023-03-01 2563 * verifier will have uncloned it (see bpf_unclone_prologue()) already. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2564 * The pointer can be directly written into. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2565 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2566 * 2) Some portion of the requested slice is in the paged buffer area. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2567 * In this case, the requested data will be copied out into the buffer 66e3a13e7c2c44 Joanne Koong 2023-03-01 2568 * and the returned pointer will be a pointer to the buffer. The skb 66e3a13e7c2c44 Joanne Koong 2023-03-01 2569 * will not be pulled. To persist the write, the user will need to call 66e3a13e7c2c44 Joanne Koong 2023-03-01 2570 * bpf_dynptr_write(), which will pull the skb and commit the write. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2571 * 66e3a13e7c2c44 Joanne Koong 2023-03-01 2572 * Similarly for xdp programs, if the requested slice is not across xdp 66e3a13e7c2c44 Joanne Koong 2023-03-01 2573 * fragments, then a direct pointer will be returned, otherwise the data 66e3a13e7c2c44 Joanne Koong 2023-03-01 2574 * will be copied out into the buffer and the user will need to call 66e3a13e7c2c44 Joanne Koong 2023-03-01 2575 * bpf_dynptr_write() to commit changes. 66e3a13e7c2c44 Joanne Koong 2023-03-01 2576 */ ec3b75c0e6eb53 Daniel Xu 2024-06-08 2577 return bpf_dynptr_slice(p, offset, buffer__opt, buffer__szk); 66e3a13e7c2c44 Joanne Koong 2023-03-01 2578 } 66e3a13e7c2c44 Joanne Koong 2023-03-01 2579
Hi Daniel, kernel test robot noticed the following build warnings: [auto build test WARNING on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Xu/kbuild-bpf-Tell-pahole-to-DECL_TAG-kfuncs/20240609-052326 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/677377439845fcb9135151d1dac1102ed3d6c924.1717881178.git.dxu%40dxuuu.xyz patch subject: [PATCH bpf-next v4 09/12] bpf: treewide: Align kfunc signatures to prog point-of-view config: s390-defconfig (https://download.01.org/0day-ci/archive/20240609/202406090949.IpHo1F5q-lkp@intel.com/config) compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project d7d2d4f53fc79b4b58e8d8d08151b577c3699d4a) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240609/202406090949.IpHo1F5q-lkp@intel.com/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 <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202406090949.IpHo1F5q-lkp@intel.com/ All warnings (new ones prefixed by >>): >> fs/verity/measure.c:121: warning: Function parameter or struct member 'digest_p' not described in 'bpf_get_fsverity_digest' >> fs/verity/measure.c:121: warning: Excess function parameter 'digest_ptr' description in 'bpf_get_fsverity_digest' -- >> kernel/trace/bpf_trace.c:1384: warning: Function parameter or struct member 'data_p' not described in 'bpf_verify_pkcs7_signature' >> kernel/trace/bpf_trace.c:1384: warning: Function parameter or struct member 'sig_p' not described in 'bpf_verify_pkcs7_signature' >> kernel/trace/bpf_trace.c:1384: warning: Excess function parameter 'data_ptr' description in 'bpf_verify_pkcs7_signature' >> kernel/trace/bpf_trace.c:1384: warning: Excess function parameter 'sig_ptr' description in 'bpf_verify_pkcs7_signature' >> kernel/trace/bpf_trace.c:1459: warning: Function parameter or struct member 'value_p' not described in 'bpf_get_file_xattr' >> kernel/trace/bpf_trace.c:1459: warning: Excess function parameter 'value_ptr' description in 'bpf_get_file_xattr' vim +121 fs/verity/measure.c 67814c00de3161 Song Liu 2023-11-29 110 67814c00de3161 Song Liu 2023-11-29 111 /** 67814c00de3161 Song Liu 2023-11-29 112 * bpf_get_fsverity_digest: read fsverity digest of file 67814c00de3161 Song Liu 2023-11-29 113 * @file: file to get digest from 67814c00de3161 Song Liu 2023-11-29 114 * @digest_ptr: (out) dynptr for struct fsverity_digest 67814c00de3161 Song Liu 2023-11-29 115 * 67814c00de3161 Song Liu 2023-11-29 116 * Read fsverity_digest of *file* into *digest_ptr*. 67814c00de3161 Song Liu 2023-11-29 117 * 67814c00de3161 Song Liu 2023-11-29 118 * Return: 0 on success, a negative value on error. 67814c00de3161 Song Liu 2023-11-29 119 */ ec3b75c0e6eb53 Daniel Xu 2024-06-08 120 __bpf_kfunc int bpf_get_fsverity_digest(struct file *file, struct bpf_dynptr *digest_p) 67814c00de3161 Song Liu 2023-11-29 @121 { ec3b75c0e6eb53 Daniel Xu 2024-06-08 122 struct bpf_dynptr_kern *digest_ptr = (struct bpf_dynptr_kern *)digest_p; 67814c00de3161 Song Liu 2023-11-29 123 const struct inode *inode = file_inode(file); 67814c00de3161 Song Liu 2023-11-29 124 u32 dynptr_sz = __bpf_dynptr_size(digest_ptr); 67814c00de3161 Song Liu 2023-11-29 125 struct fsverity_digest *arg; 67814c00de3161 Song Liu 2023-11-29 126 const struct fsverity_info *vi; 67814c00de3161 Song Liu 2023-11-29 127 const struct fsverity_hash_alg *hash_alg; 67814c00de3161 Song Liu 2023-11-29 128 int out_digest_sz; 67814c00de3161 Song Liu 2023-11-29 129 67814c00de3161 Song Liu 2023-11-29 130 if (dynptr_sz < sizeof(struct fsverity_digest)) 67814c00de3161 Song Liu 2023-11-29 131 return -EINVAL; 67814c00de3161 Song Liu 2023-11-29 132 67814c00de3161 Song Liu 2023-11-29 133 arg = __bpf_dynptr_data_rw(digest_ptr, dynptr_sz); 67814c00de3161 Song Liu 2023-11-29 134 if (!arg) 67814c00de3161 Song Liu 2023-11-29 135 return -EINVAL; 67814c00de3161 Song Liu 2023-11-29 136 67814c00de3161 Song Liu 2023-11-29 137 if (!IS_ALIGNED((uintptr_t)arg, __alignof__(*arg))) 67814c00de3161 Song Liu 2023-11-29 138 return -EINVAL; 67814c00de3161 Song Liu 2023-11-29 139 67814c00de3161 Song Liu 2023-11-29 140 vi = fsverity_get_info(inode); 67814c00de3161 Song Liu 2023-11-29 141 if (!vi) 67814c00de3161 Song Liu 2023-11-29 142 return -ENODATA; /* not a verity file */ 67814c00de3161 Song Liu 2023-11-29 143 67814c00de3161 Song Liu 2023-11-29 144 hash_alg = vi->tree_params.hash_alg; 67814c00de3161 Song Liu 2023-11-29 145 67814c00de3161 Song Liu 2023-11-29 146 arg->digest_algorithm = hash_alg - fsverity_hash_algs; 67814c00de3161 Song Liu 2023-11-29 147 arg->digest_size = hash_alg->digest_size; 67814c00de3161 Song Liu 2023-11-29 148 67814c00de3161 Song Liu 2023-11-29 149 out_digest_sz = dynptr_sz - sizeof(struct fsverity_digest); 67814c00de3161 Song Liu 2023-11-29 150 67814c00de3161 Song Liu 2023-11-29 151 /* copy digest */ 67814c00de3161 Song Liu 2023-11-29 152 memcpy(arg->digest, vi->file_digest, min_t(int, hash_alg->digest_size, out_digest_sz)); 67814c00de3161 Song Liu 2023-11-29 153 67814c00de3161 Song Liu 2023-11-29 154 /* fill the extra buffer with zeros */ 67814c00de3161 Song Liu 2023-11-29 155 if (out_digest_sz > hash_alg->digest_size) 67814c00de3161 Song Liu 2023-11-29 156 memset(arg->digest + arg->digest_size, 0, out_digest_sz - hash_alg->digest_size); 67814c00de3161 Song Liu 2023-11-29 157 67814c00de3161 Song Liu 2023-11-29 158 return 0; 67814c00de3161 Song Liu 2023-11-29 159 } 67814c00de3161 Song Liu 2023-11-29 160
diff --git a/fs/verity/measure.c b/fs/verity/measure.c index 3969d54158d1..7af0f7f8a6f3 100644 --- a/fs/verity/measure.c +++ b/fs/verity/measure.c @@ -117,8 +117,9 @@ __bpf_kfunc_start_defs(); * * Return: 0 on success, a negative value on error. */ -__bpf_kfunc int bpf_get_fsverity_digest(struct file *file, struct bpf_dynptr_kern *digest_ptr) +__bpf_kfunc int bpf_get_fsverity_digest(struct file *file, struct bpf_dynptr *digest_p) { + struct bpf_dynptr_kern *digest_ptr = (struct bpf_dynptr_kern *)digest_p; const struct inode *inode = file_inode(file); u32 dynptr_sz = __bpf_dynptr_size(digest_ptr); struct fsverity_digest *arg; diff --git a/include/linux/bpf.h b/include/linux/bpf.h index a834f4b761bc..f636b4998bf7 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -3265,8 +3265,8 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, struct bpf_insn *insn_buf, struct bpf_prog *prog, u32 *target_size); -int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, - struct bpf_dynptr_kern *ptr); +int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, + struct bpf_dynptr *ptr); #else static inline bool bpf_sock_common_is_valid_access(int off, int size, enum bpf_access_type type, @@ -3288,8 +3288,8 @@ static inline u32 bpf_sock_convert_ctx_access(enum bpf_access_type type, { return 0; } -static inline int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, - struct bpf_dynptr_kern *ptr) +static inline int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, + struct bpf_dynptr *ptr) { return -EOPNOTSUPP; } diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c index 2bee4af91e38..3c1de0e5c0bd 100644 --- a/kernel/bpf/crypto.c +++ b/kernel/bpf/crypto.c @@ -311,11 +311,15 @@ static int bpf_crypto_crypt(const struct bpf_crypto_ctx *ctx, * Decrypts provided buffer using IV data and the crypto context. Crypto context must be configured. */ __bpf_kfunc int bpf_crypto_decrypt(struct bpf_crypto_ctx *ctx, - const struct bpf_dynptr_kern *src, - const struct bpf_dynptr_kern *dst, - const struct bpf_dynptr_kern *siv) + const struct bpf_dynptr *src, + const struct bpf_dynptr *dst, + const struct bpf_dynptr *siv) { - return bpf_crypto_crypt(ctx, src, dst, siv, true); + const struct bpf_dynptr_kern *src_kern = (struct bpf_dynptr_kern *)src; + const struct bpf_dynptr_kern *dst_kern = (struct bpf_dynptr_kern *)dst; + const struct bpf_dynptr_kern *siv_kern = (struct bpf_dynptr_kern *)siv; + + return bpf_crypto_crypt(ctx, src_kern, dst_kern, siv_kern, true); } /** @@ -328,11 +332,15 @@ __bpf_kfunc int bpf_crypto_decrypt(struct bpf_crypto_ctx *ctx, * Encrypts provided buffer using IV data and the crypto context. Crypto context must be configured. */ __bpf_kfunc int bpf_crypto_encrypt(struct bpf_crypto_ctx *ctx, - const struct bpf_dynptr_kern *src, - const struct bpf_dynptr_kern *dst, - const struct bpf_dynptr_kern *siv) + const struct bpf_dynptr *src, + const struct bpf_dynptr *dst, + const struct bpf_dynptr *siv) { - return bpf_crypto_crypt(ctx, src, dst, siv, false); + const struct bpf_dynptr_kern *src_kern = (struct bpf_dynptr_kern *)src; + const struct bpf_dynptr_kern *dst_kern = (struct bpf_dynptr_kern *)dst; + const struct bpf_dynptr_kern *siv_kern = (struct bpf_dynptr_kern *)siv; + + return bpf_crypto_crypt(ctx, src_kern, dst_kern, siv_kern, false); } __bpf_kfunc_end_defs(); diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 6f1abcb4b084..3ac521c48bba 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -2459,9 +2459,10 @@ __bpf_kfunc struct task_struct *bpf_task_from_pid(s32 pid) * provided buffer, with its contents containing the data, if unable to obtain * direct pointer) */ -__bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset, +__bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset, void *buffer__opt, u32 buffer__szk) { + const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; enum bpf_dynptr_type type; u32 len = buffer__szk; int err; @@ -2543,9 +2544,11 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset * provided buffer, with its contents containing the data, if unable to obtain * direct pointer) */ -__bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, +__bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *p, u32 offset, void *buffer__opt, u32 buffer__szk) { + const struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; + if (!ptr->data || __bpf_dynptr_is_rdonly(ptr)) return NULL; @@ -2571,11 +2574,12 @@ __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 o * will be copied out into the buffer and the user will need to call * bpf_dynptr_write() to commit changes. */ - return bpf_dynptr_slice(ptr, offset, buffer__opt, buffer__szk); + return bpf_dynptr_slice(p, offset, buffer__opt, buffer__szk); } -__bpf_kfunc int bpf_dynptr_adjust(struct bpf_dynptr_kern *ptr, u32 start, u32 end) +__bpf_kfunc int bpf_dynptr_adjust(const struct bpf_dynptr *p, u32 start, u32 end) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; u32 size; if (!ptr->data || start > end) @@ -2592,36 +2596,45 @@ __bpf_kfunc int bpf_dynptr_adjust(struct bpf_dynptr_kern *ptr, u32 start, u32 en return 0; } -__bpf_kfunc bool bpf_dynptr_is_null(struct bpf_dynptr_kern *ptr) +__bpf_kfunc bool bpf_dynptr_is_null(const struct bpf_dynptr *p) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; + return !ptr->data; } -__bpf_kfunc bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr) +__bpf_kfunc bool bpf_dynptr_is_rdonly(const struct bpf_dynptr *p) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; + if (!ptr->data) return false; return __bpf_dynptr_is_rdonly(ptr); } -__bpf_kfunc __u32 bpf_dynptr_size(const struct bpf_dynptr_kern *ptr) +__bpf_kfunc __u32 bpf_dynptr_size(const struct bpf_dynptr *p) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; + if (!ptr->data) return -EINVAL; return __bpf_dynptr_size(ptr); } -__bpf_kfunc int bpf_dynptr_clone(struct bpf_dynptr_kern *ptr, - struct bpf_dynptr_kern *clone__uninit) +__bpf_kfunc int bpf_dynptr_clone(const struct bpf_dynptr *p, + struct bpf_dynptr *clone__uninit) { + struct bpf_dynptr_kern *clone = (struct bpf_dynptr_kern *)clone__uninit; + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)p; + if (!ptr->data) { - bpf_dynptr_set_null(clone__uninit); + bpf_dynptr_set_null(clone); return -EINVAL; } - *clone__uninit = *ptr; + *clone = *ptr; return 0; } @@ -2986,7 +2999,9 @@ late_initcall(kfunc_init); */ const void *__bpf_dynptr_data(const struct bpf_dynptr_kern *ptr, u32 len) { - return bpf_dynptr_slice(ptr, 0, NULL, len); + const struct bpf_dynptr *p = (struct bpf_dynptr *)ptr; + + return bpf_dynptr_slice(p, 0, NULL, len); } /* Get a pointer to dynptr data up to len bytes for read write access. If diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0808beca3837..05491b6de213 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -10910,7 +10910,7 @@ enum { }; BTF_ID_LIST(kf_arg_btf_ids) -BTF_ID(struct, bpf_dynptr_kern) +BTF_ID(struct, bpf_dynptr) BTF_ID(struct, bpf_list_head) BTF_ID(struct, bpf_list_node) BTF_ID(struct, bpf_rb_root) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index f5154c051d2c..58ae34b730df 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1378,10 +1378,12 @@ __bpf_kfunc void bpf_key_put(struct bpf_key *bkey) * * Return: 0 on success, a negative value on error. */ -__bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr_kern *data_ptr, - struct bpf_dynptr_kern *sig_ptr, +__bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p, + struct bpf_dynptr *sig_p, struct bpf_key *trusted_keyring) { + struct bpf_dynptr_kern *data_ptr = (struct bpf_dynptr_kern *)data_p; + struct bpf_dynptr_kern *sig_ptr = (struct bpf_dynptr_kern *)sig_p; const void *data, *sig; u32 data_len, sig_len; int ret; @@ -1453,8 +1455,9 @@ __bpf_kfunc_start_defs(); * Return: 0 on success, a negative value on error. */ __bpf_kfunc int bpf_get_file_xattr(struct file *file, const char *name__str, - struct bpf_dynptr_kern *value_ptr) + struct bpf_dynptr *value_p) { + struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p; struct dentry *dentry; u32 value_len; void *value; diff --git a/net/core/filter.c b/net/core/filter.c index 7c46ecba3b01..73722790cee3 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -11859,28 +11859,34 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) } __bpf_kfunc_start_defs(); -__bpf_kfunc int bpf_dynptr_from_skb(struct sk_buff *skb, u64 flags, - struct bpf_dynptr_kern *ptr__uninit) +__bpf_kfunc int bpf_dynptr_from_skb(struct __sk_buff *s, u64 flags, + struct bpf_dynptr *ptr__uninit) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; + struct sk_buff *skb = (struct sk_buff *)s; + if (flags) { - bpf_dynptr_set_null(ptr__uninit); + bpf_dynptr_set_null(ptr); return -EINVAL; } - bpf_dynptr_init(ptr__uninit, skb, BPF_DYNPTR_TYPE_SKB, 0, skb->len); + bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB, 0, skb->len); return 0; } -__bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_buff *xdp, u64 flags, - struct bpf_dynptr_kern *ptr__uninit) +__bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_md *x, u64 flags, + struct bpf_dynptr *ptr__uninit) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; + struct xdp_buff *xdp = (struct xdp_buff *)x; + if (flags) { - bpf_dynptr_set_null(ptr__uninit); + bpf_dynptr_set_null(ptr); return -EINVAL; } - bpf_dynptr_init(ptr__uninit, xdp, BPF_DYNPTR_TYPE_XDP, 0, xdp_get_buff_len(xdp)); + bpf_dynptr_init(ptr, xdp, BPF_DYNPTR_TYPE_XDP, 0, xdp_get_buff_len(xdp)); return 0; } @@ -11906,10 +11912,11 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern, return 0; } -__bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct sk_buff *skb, struct sock *sk, +__bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, struct bpf_tcp_req_attrs *attrs, int attrs__sz) { #if IS_ENABLED(CONFIG_SYN_COOKIES) + struct sk_buff *skb = (struct sk_buff *)s; const struct request_sock_ops *ops; struct inet_request_sock *ireq; struct tcp_request_sock *treq; @@ -12004,16 +12011,17 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct sk_buff *skb, struct sock *sk, __bpf_kfunc_end_defs(); -int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, - struct bpf_dynptr_kern *ptr__uninit) +int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, + struct bpf_dynptr *ptr__uninit) { + struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; int err; err = bpf_dynptr_from_skb(skb, flags, ptr__uninit); if (err) return err; - bpf_dynptr_set_rdonly(ptr__uninit); + bpf_dynptr_set_rdonly(ptr); return 0; } diff --git a/tools/testing/selftests/bpf/progs/ip_check_defrag.c b/tools/testing/selftests/bpf/progs/ip_check_defrag.c index 1c2b6c1616b0..645b2c9f7867 100644 --- a/tools/testing/selftests/bpf/progs/ip_check_defrag.c +++ b/tools/testing/selftests/bpf/progs/ip_check_defrag.c @@ -12,7 +12,7 @@ #define IP_OFFSET 0x1FFF #define NEXTHDR_FRAGMENT 44 -extern int bpf_dynptr_from_skb(struct sk_buff *skb, __u64 flags, +extern int bpf_dynptr_from_skb(struct __sk_buff *skb, __u64 flags, struct bpf_dynptr *ptr__uninit) __ksym; extern void *bpf_dynptr_slice(const struct bpf_dynptr *ptr, uint32_t offset, void *buffer, uint32_t buffer__sz) __ksym; @@ -42,7 +42,7 @@ static bool is_frag_v6(struct ipv6hdr *ip6h) return ip6h->nexthdr == NEXTHDR_FRAGMENT; } -static int handle_v4(struct sk_buff *skb) +static int handle_v4(struct __sk_buff *skb) { struct bpf_dynptr ptr; u8 iph_buf[20] = {}; @@ -64,7 +64,7 @@ static int handle_v4(struct sk_buff *skb) return NF_ACCEPT; } -static int handle_v6(struct sk_buff *skb) +static int handle_v6(struct __sk_buff *skb) { struct bpf_dynptr ptr; struct ipv6hdr *ip6h; @@ -89,9 +89,9 @@ static int handle_v6(struct sk_buff *skb) SEC("netfilter") int defrag(struct bpf_nf_ctx *ctx) { - struct sk_buff *skb = ctx->skb; + struct __sk_buff *skb = (struct __sk_buff *)ctx->skb; - switch (bpf_ntohs(skb->protocol)) { + switch (bpf_ntohs(ctx->skb->protocol)) { case ETH_P_IP: return handle_v4(skb); case ETH_P_IPV6: diff --git a/tools/testing/selftests/bpf/progs/verifier_netfilter_ctx.c b/tools/testing/selftests/bpf/progs/verifier_netfilter_ctx.c index 65bba330e7e5..ab9f9f2620ed 100644 --- a/tools/testing/selftests/bpf/progs/verifier_netfilter_ctx.c +++ b/tools/testing/selftests/bpf/progs/verifier_netfilter_ctx.c @@ -79,7 +79,7 @@ int with_invalid_ctx_access_test5(struct bpf_nf_ctx *ctx) return NF_ACCEPT; } -extern int bpf_dynptr_from_skb(struct sk_buff *skb, __u64 flags, +extern int bpf_dynptr_from_skb(struct __sk_buff *skb, __u64 flags, struct bpf_dynptr *ptr__uninit) __ksym; extern void *bpf_dynptr_slice(const struct bpf_dynptr *ptr, uint32_t offset, void *buffer, uint32_t buffer__sz) __ksym; @@ -90,8 +90,8 @@ __success __failure_unpriv __retval(0) int with_valid_ctx_access_test6(struct bpf_nf_ctx *ctx) { + struct __sk_buff *skb = (struct __sk_buff *)ctx->skb; const struct nf_hook_state *state = ctx->state; - struct sk_buff *skb = ctx->skb; const struct iphdr *iph; const struct tcphdr *th; u8 buffer_iph[20] = {}; @@ -99,7 +99,7 @@ int with_valid_ctx_access_test6(struct bpf_nf_ctx *ctx) struct bpf_dynptr ptr; uint8_t ihl; - if (skb->len <= 20 || bpf_dynptr_from_skb(skb, 0, &ptr)) + if (ctx->skb->len <= 20 || bpf_dynptr_from_skb(skb, 0, &ptr)) return NF_ACCEPT; iph = bpf_dynptr_slice(&ptr, 0, buffer_iph, sizeof(buffer_iph));
Previously, kfunc declarations in bpf_kfuncs.h (and others) used "user facing" types for kfuncs prototypes while the actual kfunc definitions used "kernel facing" types. More specifically: bpf_dynptr vs bpf_dynptr_kern, __sk_buff vs sk_buff, and xdp_md vs xdp_buff. It wasn't an issue before, as the verifier allows aliased types. However, since we are now generating kfunc prototypes in vmlinux.h (in addition to keeping bpf_kfuncs.h around), this conflict creates compilation errors. Fix this conflict by using "user facing" types in kfunc definitions. This results in more casts, but otherwise has no additional runtime cost. Note, similar to 5b268d1ebcdc ("bpf: Have bpf_rdonly_cast() take a const pointer"), we also make kfuncs take const arguments where appropriate in order to make the kfunc more permissive. Signed-off-by: Daniel Xu <dxu@dxuuu.xyz> --- fs/verity/measure.c | 3 +- include/linux/bpf.h | 8 ++-- kernel/bpf/crypto.c | 24 ++++++++---- kernel/bpf/helpers.c | 39 +++++++++++++------ kernel/bpf/verifier.c | 2 +- kernel/trace/bpf_trace.c | 9 +++-- net/core/filter.c | 32 +++++++++------ .../selftests/bpf/progs/ip_check_defrag.c | 10 ++--- .../bpf/progs/verifier_netfilter_ctx.c | 6 +-- 9 files changed, 84 insertions(+), 49 deletions(-)