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 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).