Hi Florent, I love your patch! Perhaps something to improve: [auto build test WARNING on bpf-next/master] url: https://github.com/0day-ci/linux/commits/Florent-Revest/bpf-Add-a-ARG_PTR_TO_CONST_STR-argument-type/20210311-070306 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master config: openrisc-randconfig-r023-20210308 (attached as .config) compiler: or1k-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/c06d419a45370b897b7383625f0435873a7458fa git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Florent-Revest/bpf-Add-a-ARG_PTR_TO_CONST_STR-argument-type/20210311-070306 git checkout c06d419a45370b897b7383625f0435873a7458fa # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=openrisc If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): kernel/bpf/verifier.c: In function 'check_func_arg': kernel/bpf/verifier.c:4918:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 4918 | map_ptr = (char *)(map_addr); | ^ kernel/bpf/verifier.c: At top level: >> kernel/bpf/verifier.c:5735:5: warning: no previous prototype for 'check_bpf_snprintf_call' [-Wmissing-prototypes] 5735 | int check_bpf_snprintf_call(struct bpf_verifier_env *env, | ^~~~~~~~~~~~~~~~~~~~~~~ kernel/bpf/verifier.c: In function 'check_bpf_snprintf_call': kernel/bpf/verifier.c:5758:8: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 5758 | fmt = (char *)fmt_addr; | ^ In file included from include/linux/bpf_verifier.h:9, from kernel/bpf/verifier.c:12: kernel/bpf/verifier.c: In function 'jit_subprogs': include/linux/filter.h:363:4: warning: cast between incompatible function types from 'unsigned int (*)(const void *, const struct bpf_insn *)' to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:11865:16: note: in expansion of macro 'BPF_CAST_CALL' 11865 | insn->imm = BPF_CAST_CALL(func[subprog]->bpf_func) - | ^~~~~~~~~~~~~ kernel/bpf/verifier.c: In function 'do_misc_fixups': include/linux/filter.h:363:4: warning: cast between incompatible function types from 'void * (* const)(struct bpf_map *, void *)' to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12273:17: note: in expansion of macro 'BPF_CAST_CALL' 12273 | insn->imm = BPF_CAST_CALL(ops->map_lookup_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, void *, void *, u64)' {aka 'int (* const)(struct bpf_map *, void *, void *, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12277:17: note: in expansion of macro 'BPF_CAST_CALL' 12277 | insn->imm = BPF_CAST_CALL(ops->map_update_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, void *)' to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12281:17: note: in expansion of macro 'BPF_CAST_CALL' 12281 | insn->imm = BPF_CAST_CALL(ops->map_delete_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, void *, u64)' {aka 'int (* const)(struct bpf_map *, void *, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12285:17: note: in expansion of macro 'BPF_CAST_CALL' 12285 | insn->imm = BPF_CAST_CALL(ops->map_push_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, void *)' to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12289:17: note: in expansion of macro 'BPF_CAST_CALL' 12289 | insn->imm = BPF_CAST_CALL(ops->map_pop_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, void *)' to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12293:17: note: in expansion of macro 'BPF_CAST_CALL' 12293 | insn->imm = BPF_CAST_CALL(ops->map_peek_elem) - | ^~~~~~~~~~~~~ include/linux/filter.h:363:4: warning: cast between incompatible function types from 'int (* const)(struct bpf_map *, u32, u64)' {aka 'int (* const)(struct bpf_map *, unsigned int, long long unsigned int)'} to 'u64 (*)(u64, u64, u64, u64, u64)' {aka 'long long unsigned int (*)(long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int, long long unsigned int)'} [-Wcast-function-type] 363 | ((u64 (*)(u64, u64, u64, u64, u64))(x)) | ^ kernel/bpf/verifier.c:12297:17: note: in expansion of macro 'BPF_CAST_CALL' 12297 | insn->imm = BPF_CAST_CALL(ops->map_redirect) - | ^~~~~~~~~~~~~ vim +/check_bpf_snprintf_call +5735 kernel/bpf/verifier.c 5734 > 5735 int check_bpf_snprintf_call(struct bpf_verifier_env *env, 5736 struct bpf_reg_state *regs) 5737 { 5738 struct bpf_reg_state *fmt_reg = ®s[BPF_REG_3]; 5739 struct bpf_reg_state *data_len_reg = ®s[BPF_REG_5]; 5740 struct bpf_map *fmt_map = fmt_reg->map_ptr; 5741 int err, fmt_map_off, i, fmt_cnt = 0, memcpy_cnt = 0, num_args; 5742 u64 fmt_addr; 5743 char *fmt; 5744 5745 /* data must be an array of u64 so data_len must be a multiple of 8 */ 5746 if (data_len_reg->var_off.value & 7) 5747 return -EINVAL; 5748 num_args = data_len_reg->var_off.value / 8; 5749 5750 /* fmt being ARG_PTR_TO_CONST_STR guarantees that var_off is const 5751 * and map_direct_value_addr is set. 5752 */ 5753 fmt_map_off = fmt_reg->off + fmt_reg->var_off.value; 5754 err = fmt_map->ops->map_direct_value_addr(fmt_map, &fmt_addr, 5755 fmt_map_off); 5756 if (err) 5757 return err; 5758 fmt = (char *)fmt_addr; 5759 5760 /* We are also guaranteed that fmt+fmt_map_off is NULL terminated, we 5761 * can focus on validating the format specifiers. 5762 */ 5763 for (i = fmt_map_off; fmt[i] != '\0'; i++) { 5764 if ((!isprint(fmt[i]) && !isspace(fmt[i])) || 5765 !isascii(fmt[i])) { 5766 verbose(env, "only printable ascii for now\n"); 5767 return -EINVAL; 5768 } 5769 5770 if (fmt[i] != '%') 5771 continue; 5772 5773 if (fmt[i + 1] == '%') { 5774 i++; 5775 continue; 5776 } 5777 5778 if (fmt_cnt >= MAX_SNPRINTF_VARARGS) { 5779 verbose(env, "too many format specifiers\n"); 5780 return -E2BIG; 5781 } 5782 5783 if (fmt_cnt >= num_args) { 5784 verbose(env, "not enough parameters to print\n"); 5785 return -EINVAL; 5786 } 5787 5788 /* fmt[i] != 0 && fmt[last] == 0, so we can access fmt[i + 1] */ 5789 i++; 5790 5791 /* skip optional "[0 +-][num]" width formating field */ 5792 while (fmt[i] == '0' || fmt[i] == '+' || fmt[i] == '-' || 5793 fmt[i] == ' ') 5794 i++; 5795 if (fmt[i] >= '1' && fmt[i] <= '9') { 5796 i++; 5797 while (fmt[i] >= '0' && fmt[i] <= '9') 5798 i++; 5799 } 5800 5801 if (fmt[i] == 's') { 5802 if (memcpy_cnt >= MAX_SNPRINTF_MEMCPY) { 5803 verbose(env, "too many buffer copies\n"); 5804 return -E2BIG; 5805 } 5806 5807 fmt_cnt++; 5808 memcpy_cnt++; 5809 continue; 5810 } 5811 5812 if (fmt[i] == 'p') { 5813 if (fmt[i + 1] == 0 || fmt[i + 1] == 'K' || 5814 fmt[i + 1] == 'x' || fmt[i + 1] == 'B' || 5815 fmt[i + 1] == 's' || fmt[i + 1] == 'S') { 5816 fmt_cnt++; 5817 continue; 5818 } 5819 5820 /* only support "%pI4", "%pi4", "%pI6" and "%pi6". */ 5821 if (fmt[i + 1] != 'i' && fmt[i + 1] != 'I') { 5822 verbose(env, "invalid specifier %%p%c\n", 5823 fmt[i+1]); 5824 return -EINVAL; 5825 } 5826 if (fmt[i + 2] != '4' && fmt[i + 2] != '6') { 5827 verbose(env, "invalid specifier %%p%c%c\n", 5828 fmt[i+1], fmt[i+2]); 5829 return -EINVAL; 5830 } 5831 5832 if (memcpy_cnt >= MAX_SNPRINTF_MEMCPY) { 5833 verbose(env, "too many buffer copies\n"); 5834 return -E2BIG; 5835 } 5836 5837 i += 2; 5838 fmt_cnt++; 5839 memcpy_cnt++; 5840 continue; 5841 } 5842 5843 if (fmt[i] == 'l') { 5844 i++; 5845 if (fmt[i] == 'l') 5846 i++; 5847 } 5848 5849 if (fmt[i] != 'i' && fmt[i] != 'd' && fmt[i] != 'u' && 5850 fmt[i] != 'x' && fmt[i] != 'X') { 5851 verbose(env, "invalid format specifier %%%c\n", fmt[i]); 5852 return -EINVAL; 5853 } 5854 5855 fmt_cnt++; 5856 } 5857 5858 if (fmt_cnt != num_args) { 5859 verbose(env, "too many parameters to print\n"); 5860 return -EINVAL; 5861 } 5862 5863 return 0; 5864 } 5865 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org