From: Tony Lindgren <tony@atomide.com>
To: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Linus Walleij <linus.walleij@linaro.org>,
"open list:GPIO SUBSYSTEM" <linux-gpio@vger.kernel.org>,
Linux-Renesas <linux-renesas-soc@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Use after free with pinctrl_enable() and devm_pinctrl_register_and_init()
Date: Wed, 21 Mar 2018 10:07:01 -0700 [thread overview]
Message-ID: <20180321170701.GD5799@atomide.com> (raw)
In-Reply-To: <CAMuHMdW+OzGYK7zj+-jWmZwMcve7=C5gGamgH9jmdgqJ7NC7Vg@mail.gmail.com>
* Geert Uytterhoeven <geert@linux-m68k.org> [180321 15:44]:
> Hi Linus, Tony,
>
> If claiming hogs failed, pinctrl_enable() frees the pctldev, and
> destroys its mutex.
Hmm so is something also left dangling at this point?
> However, if the pin controller is registered using
> devm_pinctrl_register_and_init(), device resource management will call
> pinctrl_unregister() later. This will access the destroyed pctldev,
> which may crash the system.
Can we call pinctrl_unregister() earlier and just set
pctldev to NULL..
> With poisoning enabled (CONFIG_DEBUG_SLAB=y), the crash is imminent:
>
> sh-pfc e6050000.pin-controller: function 'foo' not supported
> sh-pfc e6050000.pin-controller: invalid function a in map table
> sh-pfc e6050000.pin-controller: error claiming hogs: -22
> sh-pfc e6050000.pin-controller: could not claim hogs: -22
> Unhandled fault: alignment exception (0x001) at 0x6b6b6c2f
> pgd = 581794e0
> [6b6b6c2f] *pgd=00000000
> Internal error: : 1 [#1] SMP ARM
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> 4.16.0-rc5-kzm9g-00484-gb3469948b11d02a0-dirty #1043
> Hardware name: Generic SH73A0 (Flattened Device Tree)
> PC is at __lock_acquire+0xd8/0x1bf0
> LR is at lock_acquire+0x98/0xb8
> pc : [<c016fc84>] lr : [<c0171f80>] psr: 20000093
> sp : df441be8 ip : df441c80 fp : 00000000
> r10: 00000000 r9 : 00000001 r8 : 00000000
> r7 : 00000000 r6 : c1084170 r5 : df5586e8 r4 : df43e040
> r3 : 6b6b6c2f r2 : 6b6b6b6b r1 : 00000000 r0 : 6b6b6b6b
> Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
> Control: 10c5387d Table: 4000404a DAC: 00000051
> Process swapper/0 (pid: 1, stack limit = 0x2557051f)
> Stack: (0xdf441be8 to 0xdf442000)
> ...
> [<c016fc84>] (__lock_acquire) from [<c0171f80>] (lock_acquire+0x98/0xb8)
> [<c0171f80>] (lock_acquire) from [<c0598888>] (__mutex_lock+0x7c/0x9ec)
> [<c0598888>] (__mutex_lock) from [<c0599210>] (mutex_lock_nested+0x18/0x20)
> [<c0599210>] (mutex_lock_nested) from [<c034cd18>]
> (pinctrl_unregister+0x48/0x158)
> [<c034cd18>] (pinctrl_unregister) from [<c03b3f30>]
> (release_nodes+0x218/0x25c)
> [<c03b3f30>] (release_nodes) from [<c03b08ac>]
> (driver_probe_device+0x200/0x318)
> [<c03b08ac>] (driver_probe_device) from [<c03aedd8>]
> (bus_for_each_drv+0x90/0xb8)
>
> My first idea was to add a !devres_find(pctldev->dev, devm_pinctrl_dev_release,
> NULL, NULL) check to the error path of pinctrl_enable(), which seems
> to work(TM).
>
> However, that's still not 100% correct and sufficient:
> - pinctrl_unregister() will do some cleanup (pinctrldev_list and debugfs) that
> should not be done,
.. or maybe we could add some state flag to prevent this?
Something like the following pseudo code with super long
names maybe :)
enum pinctrl_controller_state {
PINCTRL_STATE_NONE,
PINCTRL_STATE_REGISTERED,
PINCTRL_STATE_HOGS_CLAIMED,
PINCTRL_STATE_INITIALIZED,
PINCTRL_STATE_ENABLED,
};
> - When using pinctrl_register() or devm_pinctrl_register(), and
> pinctrl_enable() fails, all other cleanup done in pinctrl_unregister()
> never happens.
Maybe this too would get sorted out if we could call
pinctrl_unregister() safely at any point of a failed
controller init?
Regards,
Tony
prev parent reply other threads:[~2018-03-21 17:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-21 15:43 Use after free with pinctrl_enable() and devm_pinctrl_register_and_init() Geert Uytterhoeven
2018-03-21 17:07 ` Tony Lindgren [this message]
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=20180321170701.GD5799@atomide.com \
--to=tony@atomide.com \
--cc=geert@linux-m68k.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.