From 7bf8d2e616e7a58fb2abe8ae46c7382cc75bc54f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 7 Jan 2022 15:01:02 +0100 Subject: [PATCH] 4.9-stable patches added patches: i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch --- ...netdev-s-real-number-of-rx-tx-queues.patch | 86 +++++++++++++++++++ ...hift-out-of-bounds-in-qfq_init_qdisc.patch | 65 ++++++++++++++ queue-4.9/series | 2 + 3 files changed, 153 insertions(+) create mode 100644 queue-4.9/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch create mode 100644 queue-4.9/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch diff --git a/queue-4.9/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch b/queue-4.9/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch new file mode 100644 index 00000000000..64d84ef88b9 --- /dev/null +++ b/queue-4.9/i40e-fix-incorrect-netdev-s-real-number-of-rx-tx-queues.patch @@ -0,0 +1,86 @@ +From e738451d78b2f8a9635d66c6a87f304b4d965f7a Mon Sep 17 00:00:00 2001 +From: Jedrzej Jagielski +Date: Fri, 17 Dec 2021 14:29:05 +0000 +Subject: i40e: Fix incorrect netdev's real number of RX/TX queues + +From: Jedrzej Jagielski + +commit e738451d78b2f8a9635d66c6a87f304b4d965f7a upstream. + +There was a wrong queues representation in sysfs during +driver's reinitialization in case of online cpus number is +less than combined queues. It was caused by stopped +NetworkManager, which is responsible for calling vsi_open +function during driver's initialization. +In specific situation (ex. 12 cpus online) there were 16 queues +in /sys/class/net//queues. In case of modifying queues with +value higher, than number of online cpus, then it caused write +errors and other errors. +Add updating of sysfs's queues representation during driver +initialization. + +Fixes: 41c445ff0f48 ("i40e: main driver core") +Signed-off-by: Lukasz Cieplicki +Signed-off-by: Jedrzej Jagielski +Tested-by: Gurucharan G +Signed-off-by: Tony Nguyen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 32 +++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -5430,6 +5430,27 @@ int i40e_open(struct net_device *netdev) + } + + /** ++ * i40e_netif_set_realnum_tx_rx_queues - Update number of tx/rx queues ++ * @vsi: vsi structure ++ * ++ * This updates netdev's number of tx/rx queues ++ * ++ * Returns status of setting tx/rx queues ++ **/ ++static int i40e_netif_set_realnum_tx_rx_queues(struct i40e_vsi *vsi) ++{ ++ int ret; ++ ++ ret = netif_set_real_num_rx_queues(vsi->netdev, ++ vsi->num_queue_pairs); ++ if (ret) ++ return ret; ++ ++ return netif_set_real_num_tx_queues(vsi->netdev, ++ vsi->num_queue_pairs); ++} ++ ++/** + * i40e_vsi_open - + * @vsi: the VSI to open + * +@@ -5463,13 +5484,7 @@ int i40e_vsi_open(struct i40e_vsi *vsi) + goto err_setup_rx; + + /* Notify the stack of the actual queue counts. */ +- err = netif_set_real_num_tx_queues(vsi->netdev, +- vsi->num_queue_pairs); +- if (err) +- goto err_set_queues; +- +- err = netif_set_real_num_rx_queues(vsi->netdev, +- vsi->num_queue_pairs); ++ err = i40e_netif_set_realnum_tx_rx_queues(vsi); + if (err) + goto err_set_queues; + +@@ -9910,6 +9925,9 @@ struct i40e_vsi *i40e_vsi_setup(struct i + ret = i40e_config_netdev(vsi); + if (ret) + goto err_netdev; ++ ret = i40e_netif_set_realnum_tx_rx_queues(vsi); ++ if (ret) ++ goto err_netdev; + ret = register_netdev(vsi->netdev); + if (ret) + goto err_netdev; diff --git a/queue-4.9/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch b/queue-4.9/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch new file mode 100644 index 00000000000..411dcf08c46 --- /dev/null +++ b/queue-4.9/sch_qfq-prevent-shift-out-of-bounds-in-qfq_init_qdisc.patch @@ -0,0 +1,65 @@ +From 7d18a07897d07495ee140dd319b0e9265c0f68ba Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 4 Jan 2022 01:45:08 -0800 +Subject: sch_qfq: prevent shift-out-of-bounds in qfq_init_qdisc + +From: Eric Dumazet + +commit 7d18a07897d07495ee140dd319b0e9265c0f68ba upstream. + +tx_queue_len can be set to ~0U, we need to be more +careful about overflows. + +__fls(0) is undefined, as this report shows: + +UBSAN: shift-out-of-bounds in net/sched/sch_qfq.c:1430:24 +shift exponent 51770272 is too large for 32-bit type 'int' +CPU: 0 PID: 25574 Comm: syz-executor.0 Not tainted 5.16.0-rc7-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0x201/0x2d8 lib/dump_stack.c:106 + ubsan_epilogue lib/ubsan.c:151 [inline] + __ubsan_handle_shift_out_of_bounds+0x494/0x530 lib/ubsan.c:330 + qfq_init_qdisc+0x43f/0x450 net/sched/sch_qfq.c:1430 + qdisc_create+0x895/0x1430 net/sched/sch_api.c:1253 + tc_modify_qdisc+0x9d9/0x1e20 net/sched/sch_api.c:1660 + rtnetlink_rcv_msg+0x934/0xe60 net/core/rtnetlink.c:5571 + netlink_rcv_skb+0x200/0x470 net/netlink/af_netlink.c:2496 + netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] + netlink_unicast+0x814/0x9f0 net/netlink/af_netlink.c:1345 + netlink_sendmsg+0xaea/0xe60 net/netlink/af_netlink.c:1921 + sock_sendmsg_nosec net/socket.c:704 [inline] + sock_sendmsg net/socket.c:724 [inline] + ____sys_sendmsg+0x5b9/0x910 net/socket.c:2409 + ___sys_sendmsg net/socket.c:2463 [inline] + __sys_sendmsg+0x280/0x370 net/socket.c:2492 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x44/0xae + +Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_qfq.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -1439,10 +1439,8 @@ static int qfq_init_qdisc(struct Qdisc * + if (err < 0) + return err; + +- if (qdisc_dev(sch)->tx_queue_len + 1 > QFQ_MAX_AGG_CLASSES) +- max_classes = QFQ_MAX_AGG_CLASSES; +- else +- max_classes = qdisc_dev(sch)->tx_queue_len + 1; ++ max_classes = min_t(u64, (u64)qdisc_dev(sch)->tx_queue_len + 1, ++ QFQ_MAX_AGG_CLASSES); + /* max_cl_shift = floor(log_2(max_classes)) */ + max_cl_shift = __fls(max_classes); + q->max_agg_classes = 1<