stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev,
	Slawomir Stepien <slawomir.stepien@nokia.com>,
	Frank Rowand <frank.rowand@sony.com>,
	Rob Herring <robh@kernel.org>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.15 007/107] of: overlay: rework overlay apply and remove kfree()s
Date: Mon, 19 Jun 2023 12:29:51 +0200	[thread overview]
Message-ID: <20230619102141.893980369@linuxfoundation.org> (raw)
In-Reply-To: <20230619102141.541044823@linuxfoundation.org>

From: Frank Rowand <frank.rowand@sony.com>

[ Upstream commit 067c098766c6af667a9002d4e33cf1f3c998abbe ]

Fix various kfree() issues related to of_overlay_apply().
  - Double kfree() of fdt and tree when init_overlay_changeset()
    returns an error.
  - free_overlay_changeset() free the root of the unflattened
    overlay (variable tree) instead of the memory that contains
    the unflattened overlay.
  - For the case of a failure during applying an overlay, move kfree()
    of new_fdt and overlay_mem into free_overlay_changeset(), which
    is called by the function that allocated them.
  - For the case of removing an overlay, the kfree() of new_fdt and
    overlay_mem remains in free_overlay_changeset().
  - Check return value of of_fdt_unflatten_tree() for error instead
    of checking the returned value of overlay_root.
  - When storing pointers to allocated objects in ovcs, do so as
    near to the allocation as possible instead of in deeply layered
    function.

More clearly document policy related to lifetime of pointers into
overlay memory.

Double kfree()
Reported-by: Slawomir Stepien <slawomir.stepien@nokia.com>

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20220420222505.928492-3-frowand.list@gmail.com
Stable-dep-of: 39affd1fdf65 ("of: overlay: Fix missing of_node_put() in error case of init_overlay_changeset()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/devicetree/overlay-notes.rst |  30 ++-
 drivers/of/overlay.c                       | 263 ++++++++++-----------
 include/linux/of.h                         |   3 +-
 3 files changed, 153 insertions(+), 143 deletions(-)

diff --git a/Documentation/devicetree/overlay-notes.rst b/Documentation/devicetree/overlay-notes.rst
index b2b8db765b8c6..e139f22b363e9 100644
--- a/Documentation/devicetree/overlay-notes.rst
+++ b/Documentation/devicetree/overlay-notes.rst
@@ -119,10 +119,32 @@ Finally, if you need to remove all overlays in one-go, just call
 of_overlay_remove_all() which will remove every single one in the correct
 order.
 
-In addition, there is the option to register notifiers that get called on
+There is the option to register notifiers that get called on
 overlay operations. See of_overlay_notifier_register/unregister and
 enum of_overlay_notify_action for details.
 
-Note that a notifier callback is not supposed to store pointers to a device
-tree node or its content beyond OF_OVERLAY_POST_REMOVE corresponding to the
-respective node it received.
+A notifier callback for OF_OVERLAY_PRE_APPLY, OF_OVERLAY_POST_APPLY, or
+OF_OVERLAY_PRE_REMOVE may store pointers to a device tree node in the overlay
+or its content but these pointers must not persist past the notifier callback
+for OF_OVERLAY_POST_REMOVE.  The memory containing the overlay will be
+kfree()ed after OF_OVERLAY_POST_REMOVE notifiers are called.  Note that the
+memory will be kfree()ed even if the notifier for OF_OVERLAY_POST_REMOVE
+returns an error.
+
+The changeset notifiers in drivers/of/dynamic.c are a second type of notifier
+that could be triggered by applying or removing an overlay.  These notifiers
+are not allowed to store pointers to a device tree node in the overlay
+or its content.  The overlay code does not protect against such pointers
+remaining active when the memory containing the overlay is freed as a result
+of removing the overlay.
+
+Any other code that retains a pointer to the overlay nodes or data is
+considered to be a bug because after removing the overlay the pointer
+will refer to freed memory.
+
+Users of overlays must be especially aware of the overall operations that
+occur on the system to ensure that other kernel code does not retain any
+pointers to the overlay nodes or data.  Any example of an inadvertent use
+of such pointers is if a driver or subsystem module is loaded after an
+overlay has been applied, and the driver or subsystem scans the entire
+devicetree or a large portion of it, including the overlay nodes.
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 56afef5594112..119dd6a0be868 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -58,7 +58,9 @@ struct fragment {
  * @id:			changeset identifier
  * @ovcs_list:		list on which we are located
  * @new_fdt:		Memory allocated to hold unflattened aligned FDT
+ * @overlay_mem:	the memory chunk that contains @overlay_root
  * @overlay_root:	expanded device tree that contains the fragment nodes
+ * @notify_state:	most recent notify action used on overlay
  * @count:		count of fragment structures
  * @fragments:		fragment nodes in the overlay expanded device tree
  * @symbols_fragment:	last element of @fragments[] is the  __symbols__ node
@@ -68,7 +70,9 @@ struct overlay_changeset {
 	int id;
 	struct list_head ovcs_list;
 	const void *new_fdt;
+	const void *overlay_mem;
 	struct device_node *overlay_root;
+	enum of_overlay_notify_action notify_state;
 	int count;
 	struct fragment *fragments;
 	bool symbols_fragment;
@@ -115,7 +119,6 @@ void of_overlay_mutex_unlock(void)
 	mutex_unlock(&of_overlay_phandle_mutex);
 }
 
-
 static LIST_HEAD(ovcs_list);
 static DEFINE_IDR(ovcs_idr);
 
@@ -162,6 +165,8 @@ static int overlay_notify(struct overlay_changeset *ovcs,
 	struct of_overlay_notify_data nd;
 	int i, ret;
 
+	ovcs->notify_state = action;
+
 	for (i = 0; i < ovcs->count; i++) {
 		struct fragment *fragment = &ovcs->fragments[i];
 
@@ -717,53 +722,49 @@ static struct device_node *find_target(struct device_node *info_node)
 /**
  * init_overlay_changeset() - initialize overlay changeset from overlay tree
  * @ovcs:		Overlay changeset to build
- * @new_fdt:		Memory allocated to hold unflattened aligned FDT
- * @overlay_root:	Contains the overlay fragments and overlay fixup nodes
  *
  * Initialize @ovcs.  Populate @ovcs->fragments with node information from
  * the top level of @overlay_root.  The relevant top level nodes are the
  * fragment nodes and the __symbols__ node.  Any other top level node will
- * be ignored.
+ * be ignored.  Populate other @ovcs fields.
  *
  * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
- * detected in @overlay_root, or -ENOSPC if idr_alloc() error.
+ * detected in @overlay_root.  On error return, the caller of
+ * init_overlay_changeset() must call free_overlay_changeset().
  */
-static int init_overlay_changeset(struct overlay_changeset *ovcs,
-		const void *new_fdt, struct device_node *overlay_root)
+static int init_overlay_changeset(struct overlay_changeset *ovcs)
 {
 	struct device_node *node, *overlay_node;
 	struct fragment *fragment;
 	struct fragment *fragments;
-	int cnt, id, ret;
+	int cnt, ret;
+
+	/*
+	 * None of the resources allocated by this function will be freed in
+	 * the error paths.  Instead the caller of this function is required
+	 * to call free_overlay_changeset() (which will free the resources)
+	 * if error return.
+	 */
 
 	/*
 	 * Warn for some issues.  Can not return -EINVAL for these until
 	 * of_unittest_apply_overlay() is fixed to pass these checks.
 	 */
-	if (!of_node_check_flag(overlay_root, OF_DYNAMIC))
-		pr_debug("%s() overlay_root is not dynamic\n", __func__);
+	if (!of_node_check_flag(ovcs->overlay_root, OF_DYNAMIC))
+		pr_debug("%s() ovcs->overlay_root is not dynamic\n", __func__);
 
-	if (!of_node_check_flag(overlay_root, OF_DETACHED))
-		pr_debug("%s() overlay_root is not detached\n", __func__);
+	if (!of_node_check_flag(ovcs->overlay_root, OF_DETACHED))
+		pr_debug("%s() ovcs->overlay_root is not detached\n", __func__);
 
-	if (!of_node_is_root(overlay_root))
-		pr_debug("%s() overlay_root is not root\n", __func__);
-
-	ovcs->overlay_root = overlay_root;
-	ovcs->new_fdt = new_fdt;
-
-	INIT_LIST_HEAD(&ovcs->ovcs_list);
+	if (!of_node_is_root(ovcs->overlay_root))
+		pr_debug("%s() ovcs->overlay_root is not root\n", __func__);
 
 	of_changeset_init(&ovcs->cset);
 
-	id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
-	if (id <= 0)
-		return id;
-
 	cnt = 0;
 
 	/* fragment nodes */
-	for_each_child_of_node(overlay_root, node) {
+	for_each_child_of_node(ovcs->overlay_root, node) {
 		overlay_node = of_get_child_by_name(node, "__overlay__");
 		if (overlay_node) {
 			cnt++;
@@ -771,7 +772,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 		}
 	}
 
-	node = of_get_child_by_name(overlay_root, "__symbols__");
+	node = of_get_child_by_name(ovcs->overlay_root, "__symbols__");
 	if (node) {
 		cnt++;
 		of_node_put(node);
@@ -780,11 +781,12 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 	fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
 	if (!fragments) {
 		ret = -ENOMEM;
-		goto err_free_idr;
+		goto err_out;
 	}
+	ovcs->fragments = fragments;
 
 	cnt = 0;
-	for_each_child_of_node(overlay_root, node) {
+	for_each_child_of_node(ovcs->overlay_root, node) {
 		overlay_node = of_get_child_by_name(node, "__overlay__");
 		if (!overlay_node)
 			continue;
@@ -796,7 +798,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 			of_node_put(fragment->overlay);
 			ret = -EINVAL;
 			of_node_put(node);
-			goto err_free_fragments;
+			goto err_out;
 		}
 
 		cnt++;
@@ -806,7 +808,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 	 * if there is a symbols fragment in ovcs->fragments[i] it is
 	 * the final element in the array
 	 */
-	node = of_get_child_by_name(overlay_root, "__symbols__");
+	node = of_get_child_by_name(ovcs->overlay_root, "__symbols__");
 	if (node) {
 		ovcs->symbols_fragment = 1;
 		fragment = &fragments[cnt];
@@ -816,7 +818,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 		if (!fragment->target) {
 			pr_err("symbols in overlay, but not in live tree\n");
 			ret = -EINVAL;
-			goto err_free_fragments;
+			goto err_out;
 		}
 
 		cnt++;
@@ -825,20 +827,14 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
 	if (!cnt) {
 		pr_err("no fragments or symbols in overlay\n");
 		ret = -EINVAL;
-		goto err_free_fragments;
+		goto err_out;
 	}
 
-	ovcs->id = id;
 	ovcs->count = cnt;
-	ovcs->fragments = fragments;
 
 	return 0;
 
-err_free_fragments:
-	kfree(fragments);
-err_free_idr:
-	idr_remove(&ovcs_idr, id);
-
+err_out:
 	pr_err("%s() failed, ret = %d\n", __func__, ret);
 
 	return ret;
@@ -851,21 +847,34 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
 	if (ovcs->cset.entries.next)
 		of_changeset_destroy(&ovcs->cset);
 
-	if (ovcs->id)
+	if (ovcs->id) {
 		idr_remove(&ovcs_idr, ovcs->id);
+		list_del(&ovcs->ovcs_list);
+		ovcs->id = 0;
+	}
+
 
 	for (i = 0; i < ovcs->count; i++) {
 		of_node_put(ovcs->fragments[i].target);
 		of_node_put(ovcs->fragments[i].overlay);
 	}
 	kfree(ovcs->fragments);
+
 	/*
-	 * There should be no live pointers into ovcs->overlay_root and
+	 * There should be no live pointers into ovcs->overlay_mem and
 	 * ovcs->new_fdt due to the policy that overlay notifiers are not
-	 * allowed to retain pointers into the overlay devicetree.
+	 * allowed to retain pointers into the overlay devicetree other
+	 * than during the window from OF_OVERLAY_PRE_APPLY overlay
+	 * notifiers until the OF_OVERLAY_POST_REMOVE overlay notifiers.
+	 *
+	 * A memory leak will occur here if within the window.
 	 */
-	kfree(ovcs->overlay_root);
-	kfree(ovcs->new_fdt);
+
+	if (ovcs->notify_state == OF_OVERLAY_INIT ||
+	    ovcs->notify_state == OF_OVERLAY_POST_REMOVE) {
+		kfree(ovcs->overlay_mem);
+		kfree(ovcs->new_fdt);
+	}
 	kfree(ovcs);
 }
 
@@ -873,27 +882,13 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
  * internal documentation
  *
  * of_overlay_apply() - Create and apply an overlay changeset
- * @new_fdt:		Memory allocated to hold the aligned FDT
- * @overlay_root:	Expanded overlay device tree
- * @ovcs_id:		Pointer to overlay changeset id
+ * @ovcs:	overlay changeset
  *
  * Creates and applies an overlay changeset.
  *
- * If an error occurs in a pre-apply notifier, then no changes are made
- * to the device tree.
- *
- * A non-zero return value will not have created the changeset if error is from:
- *   - parameter checks
- *   - building the changeset
- *   - overlay changeset pre-apply notifier
- *
  * If an error is returned by an overlay changeset pre-apply notifier
  * then no further overlay changeset pre-apply notifier will be called.
  *
- * A non-zero return value will have created the changeset if error is from:
- *   - overlay changeset entry notifier
- *   - overlay changeset post-apply notifier
- *
  * If an error is returned by an overlay changeset post-apply notifier
  * then no further overlay changeset post-apply notifier will be called.
  *
@@ -907,64 +902,37 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
  * following attempt to apply or remove an overlay changeset will be
  * refused.
  *
- * Returns 0 on success, or a negative error number.  Overlay changeset
- * id is returned to *ovcs_id.
+ * Returns 0 on success, or a negative error number.  On error return,
+ * the caller of of_overlay_apply() must call free_overlay_changeset().
  */
 
-static int of_overlay_apply(const void *new_fdt,
-		struct device_node *overlay_root, int *ovcs_id)
+static int of_overlay_apply(struct overlay_changeset *ovcs)
 {
-	struct overlay_changeset *ovcs;
 	int ret = 0, ret_revert, ret_tmp;
 
-	/*
-	 * As of this point, fdt and tree belong to the overlay changeset.
-	 * overlay changeset code is responsible for freeing them.
-	 */
-
 	if (devicetree_corrupt()) {
 		pr_err("devicetree state suspect, refuse to apply overlay\n");
-		kfree(new_fdt);
-		kfree(overlay_root);
 		ret = -EBUSY;
 		goto out;
 	}
 
-	ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
-	if (!ovcs) {
-		kfree(new_fdt);
-		kfree(overlay_root);
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	of_overlay_mutex_lock();
-	mutex_lock(&of_mutex);
-
-	ret = of_resolve_phandles(overlay_root);
+	ret = of_resolve_phandles(ovcs->overlay_root);
 	if (ret)
-		goto err_free_tree;
+		goto out;
 
-	ret = init_overlay_changeset(ovcs, new_fdt, overlay_root);
+	ret = init_overlay_changeset(ovcs);
 	if (ret)
-		goto err_free_tree;
+		goto out;
 
-	/*
-	 * After overlay_notify(), ovcs->overlay_root related pointers may have
-	 * leaked to drivers, so can not kfree() tree, aka ovcs->overlay_tree;
-	 * and can not free memory containing aligned fdt.  The aligned fdt
-	 * is contained within the memory at ovcs->new_fdt, possibly at an
-	 * offset from ovcs->new_fdt.
-	 */
 	ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
 	if (ret) {
 		pr_err("overlay changeset pre-apply notify error %d\n", ret);
-		goto err_free_overlay_changeset;
+		goto out;
 	}
 
 	ret = build_changeset(ovcs);
 	if (ret)
-		goto err_free_overlay_changeset;
+		goto out;
 
 	ret_revert = 0;
 	ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert);
@@ -974,7 +942,7 @@ static int of_overlay_apply(const void *new_fdt,
 				 ret_revert);
 			devicetree_state_flags |= DTSF_APPLY_FAIL;
 		}
-		goto err_free_overlay_changeset;
+		goto out;
 	}
 
 	ret = __of_changeset_apply_notify(&ovcs->cset);
@@ -982,9 +950,6 @@ static int of_overlay_apply(const void *new_fdt,
 		pr_err("overlay apply changeset entry notify error %d\n", ret);
 	/* notify failure is not fatal, continue */
 
-	list_add_tail(&ovcs->ovcs_list, &ovcs_list);
-	*ovcs_id = ovcs->id;
-
 	ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
 	if (ret_tmp) {
 		pr_err("overlay changeset post-apply notify error %d\n",
@@ -993,19 +958,6 @@ static int of_overlay_apply(const void *new_fdt,
 			ret = ret_tmp;
 	}
 
-	goto out_unlock;
-
-err_free_tree:
-	kfree(new_fdt);
-	kfree(overlay_root);
-
-err_free_overlay_changeset:
-	free_overlay_changeset(ovcs);
-
-out_unlock:
-	mutex_unlock(&of_mutex);
-	of_overlay_mutex_unlock();
-
 out:
 	pr_debug("%s() err=%d\n", __func__, ret);
 
@@ -1013,15 +965,16 @@ static int of_overlay_apply(const void *new_fdt,
 }
 
 int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
-			 int *ovcs_id)
+			 int *ret_ovcs_id)
 {
 	void *new_fdt;
 	void *new_fdt_align;
+	void *overlay_mem;
 	int ret;
 	u32 size;
-	struct device_node *overlay_root = NULL;
+	struct overlay_changeset *ovcs;
 
-	*ovcs_id = 0;
+	*ret_ovcs_id = 0;
 
 	if (overlay_fdt_size < sizeof(struct fdt_header) ||
 	    fdt_check_header(overlay_fdt)) {
@@ -1033,41 +986,67 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
 	if (overlay_fdt_size < size)
 		return -EINVAL;
 
+	ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
+	if (!ovcs)
+		return -ENOMEM;
+
+	of_overlay_mutex_lock();
+	mutex_lock(&of_mutex);
+
+	/*
+	 * ovcs->notify_state must be set to OF_OVERLAY_INIT before allocating
+	 * ovcs resources, implicitly set by kzalloc() of ovcs
+	 */
+
+	ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
+	if (ovcs->id <= 0) {
+		ret = ovcs->id;
+		goto err_free_ovcs;
+	}
+
+	INIT_LIST_HEAD(&ovcs->ovcs_list);
+	list_add_tail(&ovcs->ovcs_list, &ovcs_list);
+
 	/*
 	 * Must create permanent copy of FDT because of_fdt_unflatten_tree()
 	 * will create pointers to the passed in FDT in the unflattened tree.
 	 */
 	new_fdt = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
-	if (!new_fdt)
-		return -ENOMEM;
+	if (!new_fdt) {
+		ret = -ENOMEM;
+		goto err_free_ovcs;
+	}
+	ovcs->new_fdt = new_fdt;
 
 	new_fdt_align = PTR_ALIGN(new_fdt, FDT_ALIGN_SIZE);
 	memcpy(new_fdt_align, overlay_fdt, size);
 
-	of_fdt_unflatten_tree(new_fdt_align, NULL, &overlay_root);
-	if (!overlay_root) {
+	overlay_mem = of_fdt_unflatten_tree(new_fdt_align, NULL,
+					    &ovcs->overlay_root);
+	if (!overlay_mem) {
 		pr_err("unable to unflatten overlay_fdt\n");
 		ret = -EINVAL;
-		goto out_free_new_fdt;
+		goto err_free_ovcs;
 	}
+	ovcs->overlay_mem = overlay_mem;
 
-	ret = of_overlay_apply(new_fdt, overlay_root, ovcs_id);
-	if (ret < 0) {
-		/*
-		 * new_fdt and overlay_root now belong to the overlay
-		 * changeset.
-		 * overlay changeset code is responsible for freeing them.
-		 */
-		goto out;
-	}
+	ret = of_overlay_apply(ovcs);
+	if (ret < 0)
+		goto err_free_ovcs;
+
+	mutex_unlock(&of_mutex);
+	of_overlay_mutex_unlock();
+
+	*ret_ovcs_id = ovcs->id;
 
 	return 0;
 
+err_free_ovcs:
+	free_overlay_changeset(ovcs);
 
-out_free_new_fdt:
-	kfree(new_fdt);
+	mutex_unlock(&of_mutex);
+	of_overlay_mutex_unlock();
 
-out:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(of_overlay_fdt_apply);
@@ -1204,28 +1183,26 @@ int of_overlay_remove(int *ovcs_id)
 	if (!ovcs) {
 		ret = -ENODEV;
 		pr_err("remove: Could not find overlay #%d\n", *ovcs_id);
-		goto out_unlock;
+		goto err_unlock;
 	}
 
 	if (!overlay_removal_is_ok(ovcs)) {
 		ret = -EBUSY;
-		goto out_unlock;
+		goto err_unlock;
 	}
 
 	ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE);
 	if (ret) {
 		pr_err("overlay changeset pre-remove notify error %d\n", ret);
-		goto out_unlock;
+		goto err_unlock;
 	}
 
-	list_del(&ovcs->ovcs_list);
-
 	ret_apply = 0;
 	ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
 	if (ret) {
 		if (ret_apply)
 			devicetree_state_flags |= DTSF_REVERT_FAIL;
-		goto out_unlock;
+		goto err_unlock;
 	}
 
 	ret = __of_changeset_revert_notify(&ovcs->cset);
@@ -1235,6 +1212,11 @@ int of_overlay_remove(int *ovcs_id)
 
 	*ovcs_id = 0;
 
+	/*
+	 * Note that the overlay memory will be kfree()ed by
+	 * free_overlay_changeset() even if the notifier for
+	 * OF_OVERLAY_POST_REMOVE returns an error.
+	 */
 	ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE);
 	if (ret_tmp) {
 		pr_err("overlay changeset post-remove notify error %d\n",
@@ -1245,7 +1227,12 @@ int of_overlay_remove(int *ovcs_id)
 
 	free_overlay_changeset(ovcs);
 
-out_unlock:
+err_unlock:
+	/*
+	 * If jumped over free_overlay_changeset(), then did not kfree()
+	 * overlay related memory.  This is a memory leak unless a subsequent
+	 * of_overlay_remove() of this overlay is successful.
+	 */
 	mutex_unlock(&of_mutex);
 
 out:
diff --git a/include/linux/of.h b/include/linux/of.h
index 6f1c41f109bbe..83414a0b41de5 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1486,7 +1486,8 @@ static inline bool of_device_is_system_power_controller(const struct device_node
  */
 
 enum of_overlay_notify_action {
-	OF_OVERLAY_PRE_APPLY = 0,
+	OF_OVERLAY_INIT = 0,	/* kzalloc() of ovcs sets this value */
+	OF_OVERLAY_PRE_APPLY,
 	OF_OVERLAY_POST_APPLY,
 	OF_OVERLAY_PRE_REMOVE,
 	OF_OVERLAY_POST_REMOVE,
-- 
2.39.2




  parent reply	other threads:[~2023-06-19 11:00 UTC|newest]

Thread overview: 127+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-19 10:29 [PATCH 5.15 000/107] 5.15.118-rc1 review Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 001/107] test_firmware: Use kstrtobool() instead of strtobool() Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 002/107] test_firmware: prevent race conditions by a correct implementation of locking Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 003/107] test_firmware: fix a memory leak with reqs buffer Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 004/107] ksmbd: fix slab-out-of-bounds read in smb2_handle_negotiate Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 005/107] drm/amdgpu: fix Null pointer dereference error in amdgpu_device_recover_vram Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 006/107] of: overlay: rename variables to be consistent Greg Kroah-Hartman
2023-06-19 10:29 ` Greg Kroah-Hartman [this message]
2023-06-19 10:29 ` [PATCH 5.15 008/107] of: overlay: Fix missing of_node_put() in error case of init_overlay_changeset() Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 009/107] power: supply: ab8500: Fix external_power_changed race Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 010/107] power: supply: sc27xx: " Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 011/107] power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule() Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 012/107] ARM: dts: vexpress: add missing cache properties Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 013/107] tools: gpio: fix debounce_period_us output of lsgpio Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 014/107] power: supply: Ratelimit no data debug output Greg Kroah-Hartman
2023-06-19 10:29 ` [PATCH 5.15 015/107] platform/x86: asus-wmi: Ignore WMI events with codes 0x7B, 0xC0 Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 016/107] regulator: Fix error checking for debugfs_create_dir Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 017/107] irqchip/gic-v3: Disable pseudo NMIs on Mediatek devices w/ firmware issues Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 018/107] power: supply: Fix logic checking if system is running from battery Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 019/107] btrfs: scrub: try harder to mark RAID56 block groups read-only Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 020/107] btrfs: handle memory allocation failure in btrfs_csum_one_bio Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 021/107] ASoC: soc-pcm: test if a BE can be prepared Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 022/107] parisc: Improve cache flushing for PCXL in arch_sync_dma_for_cpu() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 023/107] parisc: Flush gatt writes and adjust gatt mask in parisc_agp_mask_memory() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 024/107] MIPS: unhide PATA_PLATFORM Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 025/107] MIPS: Alchemy: fix dbdma2 Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 026/107] mips: Move initrd_start check after initrd address sanitisation Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 027/107] ASoC: dwc: move DMA init to snd_soc_dai_driver probe() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 028/107] xen/blkfront: Only check REQ_FUA for writes Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 029/107] drm:amd:amdgpu: Fix missing buffer object unlock in failure path Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 030/107] NVMe: Add MAXIO 1602 to bogus nid list Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 031/107] irqchip/gic: Correctly validate OF quirk descriptors Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 032/107] io_uring: hold uring mutex around poll removal Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 033/107] wifi: cfg80211: fix locking in regulatory disconnect Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 034/107] wifi: cfg80211: fix double lock bug in reg_wdev_chan_valid() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 035/107] epoll: ep_autoremove_wake_function should use list_del_init_careful Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 036/107] ocfs2: fix use-after-free when unmounting read-only filesystem Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 037/107] ocfs2: check new file size on fallocate call Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 038/107] nios2: dts: Fix tse_mac "max-frame-size" property Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 039/107] nilfs2: fix incomplete buffer cleanup in nilfs_btnode_abort_change_key() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 040/107] nilfs2: fix possible out-of-bounds segment allocation in resize ioctl Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 041/107] kexec: support purgatories with .text.hot sections Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 042/107] x86/purgatory: remove PGO flags Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 043/107] powerpc/purgatory: " Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 044/107] ALSA: usb-audio: Add quirk flag for HEM devices to enable native DSD playback Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 045/107] dm thin metadata: check fail_io before using data_sm Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 046/107] nouveau: fix client work fence deletion race Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 047/107] RDMA/uverbs: Restrict usage of privileged QKEYs Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 048/107] net: usb: qmi_wwan: add support for Compal RXM-G1 Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 049/107] drm/amd/display: edp do not add non-edid timings Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 050/107] drm/amdgpu: add missing radeon secondary PCI ID Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 051/107] ALSA: hda/realtek: Add a quirk for Compaq N14JP6 Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 052/107] Remove DECnet support from kernel Greg Kroah-Hartman
2023-09-11 13:47   ` Donald Buczek
2023-09-11 13:54     ` Greg Kroah-Hartman
2023-09-12  7:47       ` Donald Buczek
2023-09-12  8:15         ` Greg Kroah-Hartman
2023-09-13  7:40           ` Donald Buczek
2023-09-13  7:50             ` Greg Kroah-Hartman
2023-09-13  7:42           ` [PATCH 5.15 052/107] Remove DECnet support from kernelail Stephen Hemminger
2023-06-19 10:30 ` [PATCH 5.15 053/107] thunderbolt: dma_test: Use correct value for absent rings when creating paths Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 054/107] thunderbolt: Mask ring interrupt on Intel hardware as well Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 055/107] USB: serial: option: add Quectel EM061KGL series Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 056/107] serial: lantiq: add missing interrupt ack Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 057/107] usb: dwc3: gadget: Reset num TRBs before giving back the request Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 058/107] RDMA/rtrs: Fix the last iu->buf leak in err path Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 059/107] RDMA/rtrs: Fix rxe_dealloc_pd warning Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 060/107] RDMA/rxe: Fix packet length checks Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 061/107] spi: fsl-dspi: avoid SCK glitches with continuous transfers Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 062/107] netfilter: nf_tables: integrate pipapo into commit protocol Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 063/107] netfilter: nfnetlink: skip error delivery on batch in case of ENOMEM Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 064/107] netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 065/107] net: enetc: correct the indexes of highest and 2nd highest TCs Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 066/107] ping6: Fix send to link-local addresses with VRF Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 067/107] net/sched: simplify tcf_pedit_act Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 068/107] net/sched: act_pedit: remove extra check for key type Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 069/107] net/sched: act_pedit: Parse L3 Header for L4 offset Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 070/107] net/sched: cls_u32: Fix reference counter leak leading to overflow Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 071/107] RDMA/rxe: Remove the unused variable obj Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 072/107] RDMA/rxe: Removed unused name from rxe_task struct Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 073/107] RDMA/rxe: Fix the use-before-initialization error of resp_pkts Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 074/107] iavf: remove mask from iavf_irq_enable_queues() Greg Kroah-Hartman
2023-06-19 10:30 ` [PATCH 5.15 075/107] octeontx2-af: fixed resource availability check Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 076/107] octeontx2-af: fix lbk link credits on cn10k Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 077/107] RDMA/mlx5: Initiate dropless RQ for RAW Ethernet functions Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 078/107] RDMA/cma: Always set static rate to 0 for RoCE Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 079/107] IB/uverbs: Fix to consider event queue closing also upon non-blocking mode Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 080/107] IB/isert: Fix dead lock in ib_isert Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 081/107] IB/isert: Fix possible list corruption in CMA handler Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 082/107] IB/isert: Fix incorrect release of isert connection Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 083/107] net: ethtool: correct MAX attribute value for stats Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 084/107] ipvlan: fix bound dev checking for IPv6 l3s mode Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 085/107] sctp: fix an error code in sctp_sf_eat_auth() Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 086/107] igc: Clean the TX buffer and TX descriptor ring Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 087/107] igb: fix nvm.ops.read() error handling Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 088/107] drm/nouveau: dont detect DSM for non-NVIDIA device Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 089/107] drm/nouveau/dp: check for NULL nv_connector->native_mode Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 090/107] drm/nouveau: add nv_encoder pointer check for NULL Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 091/107] cifs: fix lease break oops in xfstest generic/098 Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 092/107] ext4: drop the call to ext4_error() from ext4_get_group_info() Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 093/107] net/sched: cls_api: Fix lockup on flushing explicitly created chain Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 094/107] net: lapbether: only support ethernet devices Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 095/107] dm: dont lock fs when the map is NULL during suspend or resume Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 096/107] net: tipc: resize nlattr array to correct size Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 097/107] selftests/ptp: Fix timestamp printf format for PTP_SYS_OFFSET Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 098/107] afs: Fix vlserver probe RTT handling Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 099/107] cgroup: always put cset in cgroup_css_set_put_fork Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 100/107] rcu/kvfree: Avoid freeing new kfree_rcu() memory after old grace period Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 101/107] neighbour: Remove unused inline function neigh_key_eq16() Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 102/107] net: Remove unused inline function dst_hold_and_use() Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 103/107] net: Remove DECnet leftovers from flow.h Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 104/107] neighbour: delete neigh_lookup_nodev as not used Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 105/107] of: overlay: add entry to of_overlay_action_name[] Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 106/107] mmc: block: ensure error propagation for non-blk Greg Kroah-Hartman
2023-06-19 10:31 ` [PATCH 5.15 107/107] nilfs2: reject devices with insufficient block count Greg Kroah-Hartman
2023-06-19 13:46 ` [PATCH 5.15 000/107] 5.15.118-rc1 review Florian Fainelli
2023-06-20  9:17 ` Chris Paterson
2023-06-20  9:35 ` Harshit Mogalapalli
2023-06-20 10:21 ` Jon Hunter
2023-06-20 11:34 ` Sudip Mukherjee (Codethink)
2023-06-20 13:46 ` Naresh Kamboju
2023-06-20 17:07 ` Allen Pais
2023-06-20 21:04 ` Shuah Khan
2023-06-21 13:59   ` Greg Kroah-Hartman
2023-06-22 18:46     ` Shuah Khan
2023-06-20 21:31 ` Ron Economos
2023-06-21  0:39 ` Guenter Roeck

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=20230619102141.893980369@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=frank.rowand@sony.com \
    --cc=patches@lists.linux.dev \
    --cc=robh@kernel.org \
    --cc=sashal@kernel.org \
    --cc=slawomir.stepien@nokia.com \
    --cc=stable@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).