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