mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, lee.jones@linaro.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Vlad Buslov <vladbu@mellanox.com>,
	Jiri Pirko <jiri@mellanox.com>,
	"David S. Miller" <davem@davemloft.net>,
	syzbot+5f229e48cccc804062c0@syzkaller.appspotmail.com
Subject: [PATCH 4.19 14/74] net: sched: use Qdisc rcu API instead of relying on rtnl lock
Date: Mon, 13 Dec 2021 10:29:45 +0100	[thread overview]
Message-ID: <20211213092931.262028851@linuxfoundation.org> (raw)
In-Reply-To: <20211213092930.763200615@linuxfoundation.org>

From: Vlad Buslov <vladbu@mellanox.com>

[ Upstream commit e368fdb61d8e7c67ac70791b23345b26d7bbc661 ]

As a preparation from removing rtnl lock dependency from rules update path,
use Qdisc rcu and reference counting capabilities instead of relying on
rtnl lock while working with Qdiscs. Create new tcf_block_release()
function, and use it to free resources taken by tcf_block_find().
Currently, this function only releases Qdisc and it is extended in next
patches in this series.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[Lee: Sent to Stable]
Link: https://syzkaller.appspot.com/bug?id=d7e411c5472dd5da33d8cc921ccadc747743a568
Reported-by: syzbot+5f229e48cccc804062c0@syzkaller.appspotmail.com
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/cls_api.c |   79 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 64 insertions(+), 15 deletions(-)

--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -539,6 +539,7 @@ static struct tcf_block *tcf_block_find(
 					struct netlink_ext_ack *extack)
 {
 	struct tcf_block *block;
+	int err = 0;
 
 	if (ifindex == TCM_IFINDEX_MAGIC_BLOCK) {
 		block = tcf_block_lookup(net, block_index);
@@ -550,55 +551,93 @@ static struct tcf_block *tcf_block_find(
 		const struct Qdisc_class_ops *cops;
 		struct net_device *dev;
 
+		rcu_read_lock();
+
 		/* Find link */
-		dev = __dev_get_by_index(net, ifindex);
-		if (!dev)
+		dev = dev_get_by_index_rcu(net, ifindex);
+		if (!dev) {
+			rcu_read_unlock();
 			return ERR_PTR(-ENODEV);
+		}
 
 		/* Find qdisc */
 		if (!*parent) {
 			*q = dev->qdisc;
 			*parent = (*q)->handle;
 		} else {
-			*q = qdisc_lookup(dev, TC_H_MAJ(*parent));
+			*q = qdisc_lookup_rcu(dev, TC_H_MAJ(*parent));
 			if (!*q) {
 				NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
-				return ERR_PTR(-EINVAL);
+				err = -EINVAL;
+				goto errout_rcu;
 			}
 		}
 
+		*q = qdisc_refcount_inc_nz(*q);
+		if (!*q) {
+			NL_SET_ERR_MSG(extack, "Parent Qdisc doesn't exists");
+			err = -EINVAL;
+			goto errout_rcu;
+		}
+
 		/* Is it classful? */
 		cops = (*q)->ops->cl_ops;
 		if (!cops) {
 			NL_SET_ERR_MSG(extack, "Qdisc not classful");
-			return ERR_PTR(-EINVAL);
+			err = -EINVAL;
+			goto errout_rcu;
 		}
 
 		if (!cops->tcf_block) {
 			NL_SET_ERR_MSG(extack, "Class doesn't support blocks");
-			return ERR_PTR(-EOPNOTSUPP);
+			err = -EOPNOTSUPP;
+			goto errout_rcu;
 		}
 
+		/* At this point we know that qdisc is not noop_qdisc,
+		 * which means that qdisc holds a reference to net_device
+		 * and we hold a reference to qdisc, so it is safe to release
+		 * rcu read lock.
+		 */
+		rcu_read_unlock();
+
 		/* Do we search for filter, attached to class? */
 		if (TC_H_MIN(*parent)) {
 			*cl = cops->find(*q, *parent);
 			if (*cl == 0) {
 				NL_SET_ERR_MSG(extack, "Specified class doesn't exist");
-				return ERR_PTR(-ENOENT);
+				err = -ENOENT;
+				goto errout_qdisc;
 			}
 		}
 
 		/* And the last stroke */
 		block = cops->tcf_block(*q, *cl, extack);
-		if (!block)
-			return ERR_PTR(-EINVAL);
+		if (!block) {
+			err = -EINVAL;
+			goto errout_qdisc;
+		}
 		if (tcf_block_shared(block)) {
 			NL_SET_ERR_MSG(extack, "This filter block is shared. Please use the block index to manipulate the filters");
-			return ERR_PTR(-EOPNOTSUPP);
+			err = -EOPNOTSUPP;
+			goto errout_qdisc;
 		}
 	}
 
 	return block;
+
+errout_rcu:
+	rcu_read_unlock();
+errout_qdisc:
+	if (*q)
+		qdisc_put(*q);
+	return ERR_PTR(err);
+}
+
+static void tcf_block_release(struct Qdisc *q, struct tcf_block *block)
+{
+	if (q)
+		qdisc_put(q);
 }
 
 struct tcf_block_owner_item {
@@ -1336,6 +1375,7 @@ replay:
 errout:
 	if (chain)
 		tcf_chain_put(chain);
+	tcf_block_release(q, block);
 	if (err == -EAGAIN)
 		/* Replay the request. */
 		goto replay;
@@ -1457,6 +1497,7 @@ static int tc_del_tfilter(struct sk_buff
 errout:
 	if (chain)
 		tcf_chain_put(chain);
+	tcf_block_release(q, block);
 	return err;
 }
 
@@ -1542,6 +1583,7 @@ static int tc_get_tfilter(struct sk_buff
 errout:
 	if (chain)
 		tcf_chain_put(chain);
+	tcf_block_release(q, block);
 	return err;
 }
 
@@ -1858,7 +1900,8 @@ replay:
 	chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0;
 	if (chain_index > TC_ACT_EXT_VAL_MASK) {
 		NL_SET_ERR_MSG(extack, "Specified chain index exceeds upper limit");
-		return -EINVAL;
+		err = -EINVAL;
+		goto errout_block;
 	}
 	chain = tcf_chain_lookup(block, chain_index);
 	if (n->nlmsg_type == RTM_NEWCHAIN) {
@@ -1870,23 +1913,27 @@ replay:
 				tcf_chain_hold(chain);
 			} else {
 				NL_SET_ERR_MSG(extack, "Filter chain already exists");
-				return -EEXIST;
+				err = -EEXIST;
+				goto errout_block;
 			}
 		} else {
 			if (!(n->nlmsg_flags & NLM_F_CREATE)) {
 				NL_SET_ERR_MSG(extack, "Need both RTM_NEWCHAIN and NLM_F_CREATE to create a new chain");
-				return -ENOENT;
+				err = -ENOENT;
+				goto errout_block;
 			}
 			chain = tcf_chain_create(block, chain_index);
 			if (!chain) {
 				NL_SET_ERR_MSG(extack, "Failed to create filter chain");
-				return -ENOMEM;
+				err = -ENOMEM;
+				goto errout_block;
 			}
 		}
 	} else {
 		if (!chain || tcf_chain_held_by_acts_only(chain)) {
 			NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
-			return -EINVAL;
+			err = -EINVAL;
+			goto errout_block;
 		}
 		tcf_chain_hold(chain);
 	}
@@ -1930,6 +1977,8 @@ replay:
 
 errout:
 	tcf_chain_put(chain);
+errout_block:
+	tcf_block_release(q, block);
 	if (err == -EAGAIN)
 		/* Replay the request. */
 		goto replay;



  parent reply	other threads:[~2021-12-13  9:44 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-13  9:29 [PATCH 4.19 00/74] 4.19.221-rc1 review Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 01/74] HID: google: add eel USB id Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 02/74] HID: add hid_is_usb() function to make it simpler for USB detection Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 03/74] HID: add USB_HID dependancy to hid-prodikeys Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 04/74] HID: add USB_HID dependancy to hid-chicony Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 05/74] HID: add USB_HID dependancy on some USB HID drivers Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 06/74] HID: wacom: fix problems when device is not a valid USB device Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 07/74] HID: check for valid USB device for many HID drivers Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 08/74] can: kvaser_usb: get CAN clock frequency from device Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 09/74] can: sja1000: fix use after free in ems_pcmcia_add_card() Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 10/74] net: core: netlink: add helper refcount dec and lock function Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 11/74] net: sched: rename qdisc_destroy() to qdisc_put() Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 12/74] net: sched: extend Qdisc with rcu Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 13/74] net: sched: add helper function to take reference to Qdisc Greg Kroah-Hartman
2021-12-13  9:29 ` Greg Kroah-Hartman [this message]
2021-12-13  9:29 ` [PATCH 4.19 15/74] nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 16/74] bpf: Fix the off-by-two error in range markings Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 17/74] ice: ignore dropped packets during init Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 18/74] bonding: make tx_rebalance_counter an atomic Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 19/74] nfp: Fix memory leak in nfp_cpp_area_cache_add() Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 20/74] seg6: fix the iif in the IPv6 socket control block Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 21/74] udp: using datalen to cap max gso segments Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 22/74] IB/hfi1: Correct guard on eager buffer deallocation Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 23/74] mm: bdi: initialize bdi_min_ratio when bdi is unregistered Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 24/74] ALSA: ctl: Fix copy of updated id with element read/write Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 25/74] ALSA: pcm: oss: Fix negative period/buffer sizes Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 26/74] ALSA: pcm: oss: Limit the period size to 16MB Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 27/74] ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*() Greg Kroah-Hartman
2021-12-13  9:29 ` [PATCH 4.19 28/74] tracefs: Have new files inherit the ownership of their parent Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 29/74] clk: qcom: regmap-mux: fix parent clock lookup Greg Kroah-Hartman
2021-12-15  9:16   ` Pavel Machek
2021-12-15 10:37     ` Dmitry Baryshkov
2021-12-15 17:54       ` Pavel Machek
2021-12-13  9:30 ` [PATCH 4.19 30/74] can: pch_can: pch_can_rx_normal: fix use after free Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 31/74] can: m_can: Disable and ignore ELO interrupt Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 32/74] x86/sme: Explicitly map new EFI memmap table as encrypted Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 33/74] libata: add horkage for ASMedia 1092 Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 34/74] wait: add wake_up_pollfree() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 35/74] binder: use wake_up_pollfree() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 36/74] signalfd: " Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 37/74] aio: keep poll requests on waitqueue until completed Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 38/74] aio: fix use-after-free due to missing POLLFREE handling Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 39/74] tracefs: Set all files to the same group ownership as the mount option Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 40/74] block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2) Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 41/74] qede: validate non LSO skb length Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 42/74] ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 43/74] i40e: Fix pre-set max number of queues for VF Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 44/74] mtd: rawnand: fsmc: Take instruction delay into account Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 45/74] tools build: Remove needless libpython-version feature check that breaks test-all fast path Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 46/74] net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 47/74] net: altera: set a couple error code in probe() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 48/74] net: fec: only clear interrupt of handling queue in fec_enet_rx_queue() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 49/74] net, neigh: clear whole pneigh_entry at alloc time Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 50/74] net/qla3xxx: fix an error code in ql_adapter_up() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 51/74] USB: gadget: detect too-big endpoint 0 requests Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 52/74] USB: gadget: zero allocate endpoint 0 buffers Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 53/74] usb: core: config: fix validation of wMaxPacketValue entries Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 54/74] xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime suspending Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 55/74] usb: core: config: using bit mask instead of individual bits Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 56/74] xhci: avoid race between disable slot command and host runtime suspend Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 57/74] iio: trigger: Fix reference counting Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 58/74] iio: trigger: stm32-timer: fix MODULE_ALIAS Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 59/74] iio: stk3310: Dont return error code in interrupt handler Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 60/74] iio: mma8452: Fix trigger reference couting Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 61/74] iio: ltr501: Dont return error code in trigger handler Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 62/74] iio: kxsd9: " Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 63/74] iio: itg3200: Call iio_trigger_notify_done() on error Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 64/74] iio: dln2-adc: Fix lockdep complaint Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 65/74] iio: dln2: Check return value of devm_iio_trigger_register() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 66/74] iio: at91-sama5d2: Fix incorrect sign extension Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 67/74] iio: adc: axp20x_adc: fix charging current reporting on AXP22x Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 68/74] iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 69/74] irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 70/74] irqchip/armada-370-xp: Fix support for Multi-MSI interrupts Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 71/74] irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 72/74] irqchip: nvic: Fix offset for Interrupt Priority Offsets Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 73/74] net_sched: fix a crash in tc_new_tfilter() Greg Kroah-Hartman
2021-12-13  9:30 ` [PATCH 4.19 74/74] net: sched: make function qdisc_free_cb() static Greg Kroah-Hartman
2021-12-13 10:33 ` [PATCH 4.19 00/74] 4.19.221-rc1 review Pavel Machek
2021-12-13 16:27 ` Sudip Mukherjee
2021-12-13 18:58   ` Sudip Mukherjee
2021-12-13 19:05     ` Linus Torvalds
2021-12-13 22:23       ` Sudip Mukherjee
2021-12-13 19:55 ` Guenter Roeck
2021-12-13 20:30 ` Shuah Khan
2021-12-14  5:04 ` Naresh Kamboju
2021-12-14 12:40 ` Sudip Mukherjee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211213092931.262028851@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=davem@davemloft.net \
    --cc=jiri@mellanox.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=syzbot+5f229e48cccc804062c0@syzkaller.appspotmail.com \
    --cc=vladbu@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®