APPLIED: [SRU][X][PATCH 1/1] pinctrl: devicetree: Avoid taking direct reference to device name string
Ian May
ian.may at canonical.com
Thu Oct 22 19:42:24 UTC 2020
Applied to Xenial/master-next
Thanks,
Ian
On 2020-10-21 14:43:51 , Khalid Elmously wrote:
> From: Will Deacon <will at kernel.org>
>
> CVE-2020-0427
>
> When populating the pinctrl mapping table entries for a device, the
> 'dev_name' field for each entry is initialised to point directly at the
> string returned by 'dev_name()' for the device and subsequently used by
> 'create_pinctrl()' when looking up the mappings for the device being
> probed.
>
> This is unreliable in the presence of calls to 'dev_set_name()', which may
> reallocate the device name string leaving the pinctrl mappings with a
> dangling reference. This then leads to a use-after-free every time the
> name is dereferenced by a device probe:
>
> | BUG: KASAN: invalid-access in strcmp+0x20/0x64
> | Read of size 1 at addr 13ffffc153494b00 by task modprobe/590
> | Pointer tag: [13], memory tag: [fe]
> |
> | Call trace:
> | __kasan_report+0x16c/0x1dc
> | kasan_report+0x10/0x18
> | check_memory_region
> | __hwasan_load1_noabort+0x4c/0x54
> | strcmp+0x20/0x64
> | create_pinctrl+0x18c/0x7f4
> | pinctrl_get+0x90/0x114
> | devm_pinctrl_get+0x44/0x98
> | pinctrl_bind_pins+0x5c/0x450
> | really_probe+0x1c8/0x9a4
> | driver_probe_device+0x120/0x1d8
>
> Follow the example of sysfs, and duplicate the device name string before
> stashing it away in the pinctrl mapping entries.
>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Reported-by: Elena Petrova <lenaptr at google.com>
> Tested-by: Elena Petrova <lenaptr at google.com>
> Signed-off-by: Will Deacon <will at kernel.org>
> Link: https://lore.kernel.org/r/20191002124206.22928-1-will@kernel.org
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> (backported from commit be4c60b563edee3712d392aaeb0943a768df7023)
> [ kmously: Extra dev_err() in dt_remember_or_free_map() required
> manual merging ]
> Signed-off-by: Khalid Elmously <khalid.elmously at canonical.com>
> ---
> drivers/pinctrl/devicetree.c | 22 +++++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
> index fe04e748dfe4b..74eebcbd4e057 100644
> --- a/drivers/pinctrl/devicetree.c
> +++ b/drivers/pinctrl/devicetree.c
> @@ -40,6 +40,13 @@ struct pinctrl_dt_map {
> static void dt_free_map(struct pinctrl_dev *pctldev,
> struct pinctrl_map *map, unsigned num_maps)
> {
> + int i;
> +
> + for (i = 0; i < num_maps; ++i) {
> + kfree_const(map[i].dev_name);
> + map[i].dev_name = NULL;
> + }
> +
> if (pctldev) {
> const struct pinctrl_ops *ops = pctldev->desc->pctlops;
> ops->dt_free_map(pctldev, map, num_maps);
> @@ -73,7 +80,13 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
>
> /* Initialize common mapping table entry fields */
> for (i = 0; i < num_maps; i++) {
> - map[i].dev_name = dev_name(p->dev);
> + const char *devname;
> +
> + devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL);
> + if (!devname)
> + goto err_free_map;
> +
> + map[i].dev_name = devname;
> map[i].name = statename;
> if (pctldev)
> map[i].ctrl_dev_name = dev_name(pctldev->dev);
> @@ -83,8 +96,7 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
> dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
> if (!dt_map) {
> dev_err(p->dev, "failed to alloc struct pinctrl_dt_map\n");
> - dt_free_map(pctldev, map, num_maps);
> - return -ENOMEM;
> + goto err_free_map;
> }
>
> dt_map->pctldev = pctldev;
> @@ -93,6 +105,10 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
> list_add_tail(&dt_map->node, &p->dt_maps);
>
> return pinctrl_register_map(map, num_maps, false);
> +
> +err_free_map:
> + dt_free_map(pctldev, map, num_maps);
> + return -ENOMEM;
> }
>
> struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
> --
> 2.17.1
>
>
> --
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list