RE: [PATCH 02/36] x86, PCI: Fix memleak with get_current_resources

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: linux-pci-owner@xxxxxxxxxxxxxxx [mailto:linux-pci-owner@xxxxxxxxxxxxxxx] On Behalf Of Yinghai Lu
> Sent: Thursday, March 01, 2012 12:00 PM
> To: Jesse Barnes; Benjamin Herrenschmidt; Tony Luck; David Miller; x86
> Cc: Bjorn Helgaas; Dominik Brodowski; linux-pci@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx;
> linux-arch@xxxxxxxxxxxxxxx; Yinghai Lu
> Subject: [PATCH 02/36] x86, PCI: Fix memleak with get_current_resources
> 
> in pci_scan_acpi_root, when pci_use_crs is set, get_current_resources is used
> to get pci_root_info, and it will allocate name and res array.
> 
> later if pci_create_root_bus can not create bus (could be already there...)
> it will only free bus res list. but the name and res array is not freed.
> 
> let get_current_resource take info pointer instead have local info.
> 
> Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx>
> ---
>  arch/x86/pci/acpi.c |   49 ++++++++++++++++++++++++++++++-------------------
>  1 files changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
> index 7cc0a44..304ccf0 100644
> --- a/arch/x86/pci/acpi.c
> +++ b/arch/x86/pci/acpi.c
> @@ -305,49 +305,55 @@ static void add_resources(struct pci_root_info *info)
>  	}
>  }
> 
> +static void free_pci_root_info(struct pci_root_info *info)
> +{
> +	kfree(info->name);
> +	kfree(info->res);
> +	memset(info, 0, sizeof(struct pci_root_info));
> +}
> +

  This function leads to misunderstanding.
  I'm convinced that the function of the name starts with "free" 
  should free resources completely.


>  static void
> -get_current_resources(struct acpi_device *device, int busnum,
> +get_current_resources(struct pci_root_info *info,
> +		      struct acpi_device *device, int busnum,
>  		      int domain, struct list_head *resources)
>  {
> -	struct pci_root_info info;
>  	size_t size;
> 
> -	info.bridge = device;
> -	info.res_num = 0;
> -	info.resources = resources;
> +	info->bridge = device;
> +	info->res_num = 0;
> +	info->resources = resources;
>  	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
> -				&info);
> -	if (!info.res_num)
> +				info);
> +	if (!info->res_num)
>  		return;
> 
> -	size = sizeof(*info.res) * info.res_num;
> -	info.res = kmalloc(size, GFP_KERNEL);
> -	if (!info.res)
> +	size = sizeof(*info->res) * info->res_num;
> +	info->res = kmalloc(size, GFP_KERNEL);
> +	if (!info->res)
>  		return;
> 
> -	info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
> -	if (!info.name)
> +	info->name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum);
> +	if (!info->name)
>  		goto name_alloc_fail;
> 
> -	info.res_num = 0;
> +	info->res_num = 0;
>  	acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
> -				&info);
> +				info);
> 
>  	if (pci_use_crs) {
> -		add_resources(&info);
> +		add_resources(info);
> 
>  		return;
>  	}
> 
> -	kfree(info.name);
> -
>  name_alloc_fail:
> -	kfree(info.res);
> +	free_pci_root_info(info);
>  }
> 
>  struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
>  {
>  	struct acpi_device *device = root->device;
> +	struct pci_root_info info;
>  	int domain = root->segment;
>  	int busnum = root->secondary.start;
>  	LIST_HEAD(resources);
> @@ -392,6 +398,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
> 
>  	sd->domain = domain;
>  	sd->node = node;
> +	memset(&info, 0, sizeof(struct pci_root_info));
>  	/*
>  	 * Maybe the desired pci bus has been already scanned. In such case
>  	 * it is unnecessary to scan the pci bus with the given domain,busnum.
> @@ -405,7 +412,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
>  		memcpy(bus->sysdata, sd, sizeof(*sd));
>  		kfree(sd);
>  	} else {
> -		get_current_resources(device, busnum, domain, &resources);
> +		get_current_resources(&info, device, busnum, domain,
> +					&resources);
> 
>  		/*
>  		 * _CRS with no apertures is normal, so only fall back to
> @@ -419,6 +427,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
>  			bus->subordinate = pci_scan_child_bus(bus);
>  		else
>  			pci_free_resource_list(&resources);
> +
> +		if (!bus && pci_use_crs)
> +			free_pci_root_info(&info);
>  	}
> 
>  	/* After the PCI-E bus has been walked and all devices discovered,
> --
> 1.7.7
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux