[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <202602110246.gh5IIHrI-lkp@intel.com>
Date: Wed, 11 Feb 2026 02:34:58 +0800
From: kernel test robot <lkp@...el.com>
To: Feng Yang <yangfeng59949@....com>, davem@...emloft.net,
edumazet@...gle.com, kuba@...nel.org, pabeni@...hat.com,
horms@...nel.org, ast@...nel.org, daniel@...earbox.net,
andrii@...nel.org
Cc: oe-kbuild-all@...ts.linux.dev, bpf@...r.kernel.org,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
yangfeng59949@....com
Subject: Re: [PATCH v5] bpf: test_run: Fix the null pointer dereference issue
in bpf_lwt_xmit_push_encap
Hi Feng,
kernel test robot noticed the following build errors:
[auto build test ERROR on bpf-next/net]
[also build test ERROR on bpf-next/master bpf/master net-next/main net/main linus/master v6.19 next-20260209]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Feng-Yang/bpf-test_run-Fix-the-null-pointer-dereference-issue-in-bpf_lwt_xmit_push_encap/20260210-171138
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git net
patch link: https://lore.kernel.org/r/20260210090657.86977-1-yangfeng59949%40163.com
patch subject: [PATCH v5] bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap
config: x86_64-buildonly-randconfig-004-20260210 (https://download.01.org/0day-ci/archive/20260211/202602110246.gh5IIHrI-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260211/202602110246.gh5IIHrI-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@...el.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602110246.gh5IIHrI-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
net/bpf/test_run.c: In function 'bpf_prog_test_run_skb':
>> net/bpf/test_run.c:1162:31: warning: unused variable 'fl6' [-Wunused-variable]
1162 | struct flowi6 fl6 = {};
| ^~~
--
ld: vmlinux.o: in function `ip_route_output_key':
>> include/net/route.h:179:(.text+0x128a7e9): undefined reference to `ip_route_output_flow'
vim +/fl6 +1162 net/bpf/test_run.c
984
985 int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
986 union bpf_attr __user *uattr)
987 {
988 bool is_l2 = false, is_direct_pkt_access = false, is_lwt = false;
989 u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
990 struct net *net = current->nsproxy->net_ns;
991 struct net_device *dev = net->loopback_dev;
992 u32 headroom = NET_SKB_PAD + NET_IP_ALIGN;
993 u32 linear_sz = kattr->test.data_size_in;
994 u32 repeat = kattr->test.repeat;
995 struct dst_entry *dst = NULL;
996 struct __sk_buff *ctx = NULL;
997 struct sk_buff *skb = NULL;
998 struct sock *sk = NULL;
999 u32 retval, duration;
1000 int hh_len = ETH_HLEN;
1001 void *data = NULL;
1002 int ret;
1003
1004 if ((kattr->test.flags & ~BPF_F_TEST_SKB_CHECKSUM_COMPLETE) ||
1005 kattr->test.cpu || kattr->test.batch_size)
1006 return -EINVAL;
1007
1008 if (kattr->test.data_size_in < ETH_HLEN)
1009 return -EINVAL;
1010
1011 switch (prog->type) {
1012 case BPF_PROG_TYPE_SCHED_CLS:
1013 case BPF_PROG_TYPE_SCHED_ACT:
1014 is_direct_pkt_access = true;
1015 is_l2 = true;
1016 break;
1017 case BPF_PROG_TYPE_LWT_IN:
1018 case BPF_PROG_TYPE_LWT_OUT:
1019 case BPF_PROG_TYPE_LWT_XMIT:
1020 is_lwt = true;
1021 fallthrough;
1022 case BPF_PROG_TYPE_CGROUP_SKB:
1023 is_direct_pkt_access = true;
1024 break;
1025 default:
1026 break;
1027 }
1028
1029 ctx = bpf_ctx_init(kattr, sizeof(struct __sk_buff));
1030 if (IS_ERR(ctx))
1031 return PTR_ERR(ctx);
1032
1033 if (ctx) {
1034 if (ctx->data_end > kattr->test.data_size_in || ctx->data || ctx->data_meta) {
1035 ret = -EINVAL;
1036 goto out;
1037 }
1038 if (ctx->data_end) {
1039 /* Non-linear LWT test_run is unsupported for now. */
1040 if (is_lwt) {
1041 ret = -EINVAL;
1042 goto out;
1043 }
1044 linear_sz = max(ETH_HLEN, ctx->data_end);
1045 }
1046 }
1047
1048 linear_sz = min_t(u32, linear_sz, PAGE_SIZE - headroom - tailroom);
1049
1050 data = bpf_test_init(kattr, linear_sz, linear_sz, headroom, tailroom);
1051 if (IS_ERR(data)) {
1052 ret = PTR_ERR(data);
1053 data = NULL;
1054 goto out;
1055 }
1056
1057 sk = sk_alloc(net, AF_UNSPEC, GFP_USER, &bpf_dummy_proto, 1);
1058 if (!sk) {
1059 ret = -ENOMEM;
1060 goto out;
1061 }
1062 sock_init_data(NULL, sk);
1063
1064 skb = slab_build_skb(data);
1065 if (!skb) {
1066 ret = -ENOMEM;
1067 goto out;
1068 }
1069 skb->sk = sk;
1070
1071 data = NULL; /* data released via kfree_skb */
1072
1073 skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
1074 __skb_put(skb, linear_sz);
1075
1076 if (unlikely(kattr->test.data_size_in > linear_sz)) {
1077 void __user *data_in = u64_to_user_ptr(kattr->test.data_in);
1078 struct skb_shared_info *sinfo = skb_shinfo(skb);
1079 u32 copied = linear_sz;
1080
1081 while (copied < kattr->test.data_size_in) {
1082 struct page *page;
1083 u32 data_len;
1084
1085 if (sinfo->nr_frags == MAX_SKB_FRAGS) {
1086 ret = -ENOMEM;
1087 goto out;
1088 }
1089
1090 page = alloc_page(GFP_KERNEL);
1091 if (!page) {
1092 ret = -ENOMEM;
1093 goto out;
1094 }
1095
1096 data_len = min_t(u32, kattr->test.data_size_in - copied,
1097 PAGE_SIZE);
1098 skb_fill_page_desc(skb, sinfo->nr_frags, page, 0, data_len);
1099
1100 if (copy_from_user(page_address(page), data_in + copied,
1101 data_len)) {
1102 ret = -EFAULT;
1103 goto out;
1104 }
1105 skb->data_len += data_len;
1106 skb->truesize += PAGE_SIZE;
1107 skb->len += data_len;
1108 copied += data_len;
1109 }
1110 }
1111
1112 if (ctx && ctx->ifindex > 1) {
1113 dev = dev_get_by_index(net, ctx->ifindex);
1114 if (!dev) {
1115 ret = -ENODEV;
1116 goto out;
1117 }
1118 }
1119 skb->protocol = eth_type_trans(skb, dev);
1120 skb_reset_network_header(skb);
1121
1122 switch (skb->protocol) {
1123 case htons(ETH_P_IP):
1124 sk->sk_family = AF_INET;
1125 if (sizeof(struct iphdr) <= skb_headlen(skb)) {
1126 sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1127 sk->sk_daddr = ip_hdr(skb)->daddr;
1128 }
1129 break;
1130 #if IS_ENABLED(CONFIG_IPV6)
1131 case htons(ETH_P_IPV6):
1132 sk->sk_family = AF_INET6;
1133 if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
1134 sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1135 sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
1136 }
1137 break;
1138 #endif
1139 default:
1140 break;
1141 }
1142
1143 if (is_l2)
1144 __skb_push(skb, hh_len);
1145 if (is_direct_pkt_access)
1146 bpf_compute_data_pointers(skb);
1147
1148 ret = convert___skb_to_skb(skb, ctx);
1149 if (ret)
1150 goto out;
1151
1152 if (kattr->test.flags & BPF_F_TEST_SKB_CHECKSUM_COMPLETE) {
1153 const int off = skb_network_offset(skb);
1154 int len = skb->len - off;
1155
1156 skb->csum = skb_checksum(skb, off, len, 0);
1157 skb->ip_summed = CHECKSUM_COMPLETE;
1158 }
1159
1160 if (prog->type == BPF_PROG_TYPE_LWT_XMIT && !skb_dst(skb)) {
1161 struct flowi4 fl4 = {};
> 1162 struct flowi6 fl6 = {};
1163 struct rtable *rt;
1164
1165 switch (skb->protocol) {
1166 case htons(ETH_P_IP):
1167 if (sizeof(struct iphdr) <= skb_headlen(skb)) {
1168 fl4.saddr = ip_hdr(skb)->saddr;
1169 fl4.daddr = ip_hdr(skb)->daddr;
1170 }
1171
1172 rt = ip_route_output_key(net, &fl4);
1173 if (IS_ERR(rt)) {
1174 ret = PTR_ERR(rt);
1175 goto out;
1176 }
1177 dst = &rt->dst;
1178 break;
1179 #if IS_ENABLED(CONFIG_IPV6)
1180 case htons(ETH_P_IPV6):
1181 if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
1182 fl6.saddr = ipv6_hdr(skb)->saddr;
1183 fl6.daddr = ipv6_hdr(skb)->daddr;
1184 }
1185
1186 dst = ip6_route_output(net, NULL, &fl6);
1187 if (IS_ERR(dst)) {
1188 ret = PTR_ERR(dst);
1189 goto out;
1190 }
1191 break;
1192 #endif
1193 default:
1194 ret = -EINVAL;
1195 goto out;
1196 }
1197
1198 if (unlikely(dst->error)) {
1199 ret = dst->error;
1200 dst_release(dst);
1201 goto out;
1202 }
1203 skb_dst_set(skb, dst);
1204 }
1205 ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
1206 if (ret)
1207 goto out;
1208 if (!is_l2) {
1209 if (skb_headroom(skb) < hh_len) {
1210 int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb));
1211
1212 if (pskb_expand_head(skb, nhead, 0, GFP_USER)) {
1213 ret = -ENOMEM;
1214 goto out;
1215 }
1216 }
1217 memset(__skb_push(skb, hh_len), 0, hh_len);
1218 }
1219
1220 if (kattr->test.flags & BPF_F_TEST_SKB_CHECKSUM_COMPLETE) {
1221 const int off = skb_network_offset(skb);
1222 int len = skb->len - off;
1223 __wsum csum;
1224
1225 csum = skb_checksum(skb, off, len, 0);
1226
1227 if (csum_fold(skb->csum) != csum_fold(csum)) {
1228 ret = -EBADMSG;
1229 goto out;
1230 }
1231 }
1232
1233 convert_skb_to___skb(skb, ctx);
1234
1235 if (skb_is_nonlinear(skb))
1236 /* bpf program can never convert linear skb to non-linear */
1237 WARN_ON_ONCE(linear_sz == kattr->test.data_size_in);
1238 ret = bpf_test_finish(kattr, uattr, skb->data, skb_shinfo(skb), skb->len,
1239 skb->data_len, retval, duration);
1240 if (!ret)
1241 ret = bpf_ctx_finish(kattr, uattr, ctx,
1242 sizeof(struct __sk_buff));
1243 out:
1244 if (dev && dev != net->loopback_dev)
1245 dev_put(dev);
1246 kfree_skb(skb);
1247 kfree(data);
1248 if (sk)
1249 sk_free(sk);
1250 kfree(ctx);
1251 return ret;
1252 }
1253
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Powered by blists - more mailing lists