Re: [PATCH v4 01/11] driver: platform: Add helper for safer setting of driver_override
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
- Subject: Re: [PATCH v4 01/11] driver: platform: Add helper for safer setting of driver_override
- From: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
- Date: Tue, 15 Mar 2022 19:59:56 +0200
- Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>, "Rafael J. Wysocki" <rafael@xxxxxxxxxx>, Stuart Yoder <stuyoder@xxxxxxxxx>, Laurentiu Tudor <laurentiu.tudor@xxxxxxx>, Abel Vesa <abel.vesa@xxxxxxx>, Shawn Guo <shawnguo@xxxxxxxxxx>, Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>, Fabio Estevam <festevam@xxxxxxxxx>, "K. Y. Srinivasan" <kys@xxxxxxxxxxxxx>, Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>, Stephen Hemminger <sthemmin@xxxxxxxxxxxxx>, Wei Liu <wei.liu@xxxxxxxxxx>, Dexuan Cui <decui@xxxxxxxxxxxxx>, Bjorn Helgaas <bhelgaas@xxxxxxxxxx>, Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>, Mathieu Poirier <mathieu.poirier@xxxxxxxxxx>, Vineeth Vijayan <vneethv@xxxxxxxxxxxxx>, Peter Oberparleiter <oberpar@xxxxxxxxxxxxx>, Heiko Carstens <hca@xxxxxxxxxxxxx>, Vasily Gorbik <gor@xxxxxxxxxxxxx>, Alexander Gordeev <agordeev@xxxxxxxxxxxxx>, Christian Borntraeger <borntraeger@xxxxxxxxxxxxx>, Sven Schnelle <svens@xxxxxxxxxxxxx>, Andy Gross <agross@xxxxxxxxxx>, Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>, Mark Brown <broonie@xxxxxxxxxx>, "Michael S. Tsirkin" <mst@xxxxxxxxxx>, Jason Wang <jasowang@xxxxxxxxxx>, Linux Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>, linux-clk <linux-clk@xxxxxxxxxxxxxxx>, NXP Linux Team <linux-imx@xxxxxxx>, linux-arm Mailing List <linux-arm-kernel@xxxxxxxxxxxxxxxxxxx>, Linux on Hyper-V List <linux-hyperv@xxxxxxxxxxxxxxx>, linux-pci <linux-pci@xxxxxxxxxxxxxxx>, linux-remoteproc@xxxxxxxxxxxxxxx, linux-s390@xxxxxxxxxxxxxxx, linux-arm-msm@xxxxxxxxxxxxxxx, ALSA Development Mailing List <alsa-devel@xxxxxxxxxxxxxxxx>, linux-spi <linux-spi@xxxxxxxxxxxxxxx>, virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>, Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
- In-reply-to: <20220312132856.65163-2-krzysztof.kozlowski@canonical.com>
- References: <20220312132856.65163-1-krzysztof.kozlowski@canonical.com> <20220312132856.65163-2-krzysztof.kozlowski@canonical.com>
On Sat, Mar 12, 2022 at 5:16 PM Krzysztof Kozlowski
<krzysztof.kozlowski@xxxxxxxxxxxxx> wrote:
>
> Several core drivers and buses expect that driver_override is a
> dynamically allocated memory thus later they can kfree() it.
>
> However such assumption is not documented, there were in the past and
> there are already users setting it to a string literal. This leads to
> kfree() of static memory during device release (e.g. in error paths or
> during unbind):
>
> kernel BUG at ../mm/slub.c:3960!
> Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
> ...
> (kfree) from [<c058da50>] (platform_device_release+0x88/0xb4)
> (platform_device_release) from [<c0585be0>] (device_release+0x2c/0x90)
> (device_release) from [<c0a69050>] (kobject_put+0xec/0x20c)
> (kobject_put) from [<c0f2f120>] (exynos5_clk_probe+0x154/0x18c)
> (exynos5_clk_probe) from [<c058de70>] (platform_drv_probe+0x6c/0xa4)
> (platform_drv_probe) from [<c058b7ac>] (really_probe+0x280/0x414)
> (really_probe) from [<c058baf4>] (driver_probe_device+0x78/0x1c4)
> (driver_probe_device) from [<c0589854>] (bus_for_each_drv+0x74/0xb8)
> (bus_for_each_drv) from [<c058b48c>] (__device_attach+0xd4/0x16c)
> (__device_attach) from [<c058a638>] (bus_probe_device+0x88/0x90)
> (bus_probe_device) from [<c05871fc>] (device_add+0x3dc/0x62c)
> (device_add) from [<c075ff10>] (of_platform_device_create_pdata+0x94/0xbc)
> (of_platform_device_create_pdata) from [<c07600ec>] (of_platform_bus_create+0x1a8/0x4fc)
> (of_platform_bus_create) from [<c0760150>] (of_platform_bus_create+0x20c/0x4fc)
> (of_platform_bus_create) from [<c07605f0>] (of_platform_populate+0x84/0x118)
> (of_platform_populate) from [<c0f3c964>] (of_platform_default_populate_init+0xa0/0xb8)
> (of_platform_default_populate_init) from [<c01031f8>] (do_one_initcall+0x8c/0x404)
> (do_one_initcall) from [<c0f012c0>] (kernel_init_freeable+0x3d0/0x4d8)
> (kernel_init_freeable) from [<c0a7def0>] (kernel_init+0x8/0x114)
> (kernel_init) from [<c01010b4>] (ret_from_fork+0x14/0x20)
I believe you may remove these three.
> Provide a helper which clearly documents the usage of driver_override.
> This will allow later to reuse the helper and reduce amount of
the amount
> duplicated code.
> Convert the platform driver to use new helper and make the
a new
> driver_override field const char (it is not modified by the core).
...
> +/**
> + * driver_set_override() - Helper to set or clear driver override.
> + * @dev: Device to change
> + * @override: Address of string to change (e.g. &device->driver_override);
> + * The contents will be freed and hold newly allocated override.
> + * @s: NUL terminated string, new driver name to force a match, pass empty
NUL-terminated? (44 vs 115 occurrences)
> + * string to clear it
> + * @len: length of @s
> + *
> + * Helper to set or clear driver override in a device, intended for the cases
> + * when the driver_override field is allocated by driver/bus code.
> + *
> + * Returns: 0 on success or a negative error code on failure.
> + */
> +int driver_set_override(struct device *dev, const char **override,
> + const char *s, size_t len)
> +{
> + const char *new, *old;
> + char *cp;
> +
> + if (!dev || !override || !s)
> + return -EINVAL;
> +
> + /*
> + * The stored value will be used in sysfs show callback (sysfs_emit()),
> + * which has a length limit of PAGE_SIZE and adds a trailing newline.
> + * Thus we can store one character less to avoid truncation during sysfs
> + * show.
> + */
> + if (len >= (PAGE_SIZE - 1))
> + return -EINVAL;
> +
> + new = kstrndup(s, len, GFP_KERNEL);
> + if (!new)
> + return -ENOMEM;
> +
> + cp = strchr(new, '\n');
> + if (cp)
> + *cp = '\0';
AFAIU you may reduce memory footprint by
cp = strnchr(new, len, '\n');
if (cp)
len = s - cp;
new = kstrndup(...);
> + device_lock(dev);
> + old = *override;
> + if (cp != new) {
> + *override = new;
> + } else {
> + kfree(new);
> + *override = NULL;
> + }
> + device_unlock(dev);
> +
> + kfree(old);
> +
> + return 0;
> +}
--
With Best Regards,
Andy Shevchenko
[Index of Archives]
[Linux Kernel]
[Linux ARM (vger)]
[Linux ARM MSM]
[Linux Omap]
[Linux Arm]
[Linux Tegra]
[Fedora ARM]
[Linux for Samsung SOC]
[eCos]
[Linux Fastboot]
[Gcc Help]
[Git]
[DCCP]
[IETF Announce]
[Security]
[Linux MIPS]
[Yosemite Campsites]
|