tree: https://gitee.com/openeuler/kernel.git openEuler-1.0-LTS head: e89315eb08769716cbf7e08f49672222cf0eca47 commit: 66b5f39a891163c63bedcb59610991c784b416a4 [20434/22045] net: sched: protect against stack overflow in TC act_mirred config: arm64-randconfig-r112-20240401 (https://download.01.org/0day-ci/archive/20240404/202404041743.yILerkAq-lkp@i...) compiler: aarch64-linux-gcc (GCC) 13.2.0 reproduce: (https://download.01.org/0day-ci/archive/20240404/202404041743.yILerkAq-lkp@i...)
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/202404041743.yILerkAq-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
net/sched/act_mirred.c:217:21: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] asn:3 *__p @@ got unsigned int * @@
net/sched/act_mirred.c:217:21: sparse: expected unsigned int [noderef] asn:3 *__p net/sched/act_mirred.c:217:21: sparse: got unsigned int *
net/sched/act_mirred.c:217:21: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] asn:3 *__p @@ got unsigned int * @@
net/sched/act_mirred.c:217:21: sparse: expected unsigned int [noderef] asn:3 *__p net/sched/act_mirred.c:217:21: sparse: got unsigned int *
net/sched/act_mirred.c:217:21: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] asn:3 *__p @@ got unsigned int * @@
net/sched/act_mirred.c:217:21: sparse: expected unsigned int [noderef] asn:3 *__p net/sched/act_mirred.c:217:21: sparse: got unsigned int *
net/sched/act_mirred.c:217:21: sparse: sparse: incorrect type in initializer (different address spaces) @@ expected unsigned int [noderef] asn:3 *__p @@ got unsigned int * @@
net/sched/act_mirred.c:217:21: sparse: expected unsigned int [noderef] asn:3 *__p net/sched/act_mirred.c:217:21: sparse: got unsigned int * net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression net/sched/act_mirred.c:217:21: sparse: sparse: dereference of noderef expression In file included from include/net/act_api.h:13, from include/net/pkt_cls.h:8, from net/sched/act_mirred.c:28: In function 'net_generic', inlined from 'tc_action_net_exit' at include/net/act_api.h:137:30, inlined from 'mirred_exit_net' at net/sched/act_mirred.c:444:2: include/net/netns/generic.h:46:22: warning: array subscript <unknown> is outside array bounds of 'void *[0]' [-Warray-bounds=] 46 | ptr = ng->ptr[id]; | ~~~~~~~^~~~ include/net/netns/generic.h: In function 'mirred_exit_net': include/net/netns/generic.h:35:23: note: while referencing 'ptr' 35 | void *ptr[0]; | ^~~ In function 'net_generic', inlined from 'mirred_init_net' at net/sched/act_mirred.c:437:29: include/net/netns/generic.h:46:22: warning: array subscript <unknown> is outside array bounds of 'void *[0]' [-Warray-bounds=] 46 | ptr = ng->ptr[id]; | ~~~~~~~^~~~ include/net/netns/generic.h: In function 'mirred_init_net': include/net/netns/generic.h:35:23: note: while referencing 'ptr' 35 | void *ptr[0]; | ^~~ In function 'net_generic', inlined from 'tcf_mirred_walker' at net/sched/act_mirred.c:357:29: include/net/netns/generic.h:46:22: warning: array subscript <unknown> is outside array bounds of 'void *[0]' [-Warray-bounds=] 46 | ptr = ng->ptr[id]; | ~~~~~~~^~~~ include/net/netns/generic.h: In function 'tcf_mirred_walker': include/net/netns/generic.h:35:23: note: while referencing 'ptr' 35 | void *ptr[0]; | ^~~ In function 'net_generic', inlined from 'tcf_mirred_init' at net/sched/act_mirred.c:102:29: include/net/netns/generic.h:46:22: warning: array subscript <unknown> is outside array bounds of 'void *[0]' [-Warray-bounds=] 46 | ptr = ng->ptr[id]; | ~~~~~~~^~~~ include/net/netns/generic.h: In function 'tcf_mirred_init': include/net/netns/generic.h:35:23: note: while referencing 'ptr' 35 | void *ptr[0]; | ^~~ In function 'net_generic', inlined from 'tcf_mirred_search' at net/sched/act_mirred.c:365:29: include/net/netns/generic.h:46:22: warning: array subscript <unknown> is outside array bounds of 'void *[0]' [-Warray-bounds=] 46 | ptr = ng->ptr[id]; | ~~~~~~~^~~~ include/net/netns/generic.h: In function 'tcf_mirred_search': include/net/netns/generic.h:35:23: note: while referencing 'ptr' 35 | void *ptr[0]; | ^~~
vim +217 net/sched/act_mirred.c
199 200 static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, 201 struct tcf_result *res) 202 { 203 struct tcf_mirred *m = to_mirred(a); 204 struct sk_buff *skb2 = skb; 205 bool m_mac_header_xmit; 206 struct net_device *dev; 207 unsigned int rec_level; 208 int retval, err = 0; 209 bool use_reinsert; 210 bool want_ingress; 211 bool is_redirect; 212 bool expects_nh; 213 int m_eaction; 214 int mac_len; 215 bool at_nh; 216
217 rec_level = __this_cpu_inc_return(mirred_rec_level);
218 if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { 219 net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n", 220 netdev_name(skb->dev)); 221 __this_cpu_dec(mirred_rec_level); 222 return TC_ACT_SHOT; 223 } 224 225 tcf_lastuse_update(&m->tcf_tm); 226 bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); 227 228 m_mac_header_xmit = READ_ONCE(m->tcfm_mac_header_xmit); 229 m_eaction = READ_ONCE(m->tcfm_eaction); 230 retval = READ_ONCE(m->tcf_action); 231 dev = rcu_dereference_bh(m->tcfm_dev); 232 if (unlikely(!dev)) { 233 pr_notice_once("tc mirred: target device is gone\n"); 234 goto out; 235 } 236 237 if (unlikely(!(dev->flags & IFF_UP))) { 238 net_notice_ratelimited("tc mirred to Houston: device %s is down\n", 239 dev->name); 240 goto out; 241 } 242 243 /* we could easily avoid the clone only if called by ingress and clsact; 244 * since we can't easily detect the clsact caller, skip clone only for 245 * ingress - that covers the TC S/W datapath. 246 */ 247 is_redirect = tcf_mirred_is_act_redirect(m_eaction); 248 use_reinsert = skb_at_tc_ingress(skb) && is_redirect && 249 tcf_mirred_can_reinsert(retval); 250 if (!use_reinsert) { 251 skb2 = skb_clone(skb, GFP_ATOMIC); 252 if (!skb2) 253 goto out; 254 } 255 256 want_ingress = tcf_mirred_act_wants_ingress(m_eaction); 257 258 expects_nh = want_ingress || !m_mac_header_xmit; 259 at_nh = skb->data == skb_network_header(skb); 260 if (at_nh != expects_nh) { 261 mac_len = skb_at_tc_ingress(skb) ? skb->mac_len : 262 skb_network_header(skb) - skb_mac_header(skb); 263 if (expects_nh) { 264 /* target device/action expect data at nh */ 265 skb_pull_rcsum(skb2, mac_len); 266 } else { 267 /* target device/action expect data at mac */ 268 skb_push_rcsum(skb2, mac_len); 269 } 270 } 271 272 skb2->skb_iif = skb->dev->ifindex; 273 skb2->dev = dev; 274 275 /* mirror is always swallowed */ 276 if (is_redirect) { 277 skb2->tc_redirected = 1; 278 skb2->tc_from_ingress = skb2->tc_at_ingress; 279 280 /* let's the caller reinsert the packet, if possible */ 281 if (use_reinsert) { 282 res->ingress = want_ingress; 283 res->qstats = this_cpu_ptr(m->common.cpu_qstats); 284 skb_tc_reinsert(skb, res); 285 __this_cpu_dec(mirred_rec_level); 286 return TC_ACT_CONSUMED; 287 } 288 } 289 290 if (!want_ingress) 291 err = dev_queue_xmit(skb2); 292 else 293 err = netif_receive_skb(skb2); 294 295 if (err) { 296 out: 297 qstats_overlimit_inc(this_cpu_ptr(m->common.cpu_qstats)); 298 if (tcf_mirred_is_act_redirect(m_eaction)) 299 retval = TC_ACT_SHOT; 300 } 301 __this_cpu_dec(mirred_rec_level); 302 303 return retval; 304 } 305