Commit d8ed0fc3 authored by Sergey Shtylyov's avatar Sergey Shtylyov Committed by sanglipeng1
Browse files

pinctrl: core: handle radix_tree_insert() errors in pinctrl_register_one_pin()

stable inclusion
from stable-v5.10.218
commit 8869c2916dc1f5b4f823f1ebaa9ca465689e9c9e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IAX0QZ

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8869c2916dc1f5b4f823f1ebaa9ca465689e9c9e



--------------------------------

commit ecfe9a01 upstream.

pinctrl_register_one_pin() doesn't check the result of radix_tree_insert()
despite they both may return a negative error code.  Linus Walleij said he
has copied the radix tree code from kernel/irq/ where the functions calling
radix_tree_insert() are *void* themselves; I think it makes more sense to
propagate the errors from radix_tree_insert() upstream if we can do that...

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Signed-off-by: default avatarSergey Shtylyov <s.shtylyov@omp.ru>
Link: https://lore.kernel.org/r/20230719202253.13469-3-s.shtylyov@omp.ru


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Cc: "Hemdan, Hagar Gamal Halim" <hagarhem@amazon.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarsanglipeng1 <sanglipeng1@jd.com>
parent 96df899e
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -205,6 +205,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
				    const struct pinctrl_pin_desc *pin)
{
	struct pin_desc *pindesc;
	int error;

	pindesc = pin_desc_get(pctldev, pin->number);
	if (pindesc) {
@@ -226,18 +227,25 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
	} else {
		pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number);
		if (!pindesc->name) {
			kfree(pindesc);
			return -ENOMEM;
			error = -ENOMEM;
			goto failed;
		}
		pindesc->dynamic_name = true;
	}

	pindesc->drv_data = pin->drv_data;

	radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc);
	error = radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc);
	if (error)
		goto failed;

	pr_debug("registered pin %d (%s) on %s\n",
		 pin->number, pindesc->name, pctldev->desc->name);
	return 0;

failed:
	kfree(pindesc);
	return error;
}

static int pinctrl_register_pins(struct pinctrl_dev *pctldev,