All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mpt3sas: Fix double free warnings
@ 2020-05-08  9:18 Suganath Prabu S
  2020-05-08 10:42 ` Johannes Thumshirn
  2020-05-08 11:36 ` Dan Carpenter
  0 siblings, 2 replies; 3+ messages in thread
From: Suganath Prabu S @ 2020-05-08  9:18 UTC (permalink / raw)
  To: linux-scsi
  Cc: dan.carpenter, Sathya.Prakash, sreekanth.reddy, Suganath Prabu S

Fix below warnings from Smatch static analyser:
drivers/scsi/mpt3sas/mpt3sas_base.c:5256 _base_allocate_memory_pools()
warn: 'ioc->hpr_lookup' double freed

drivers/scsi/mpt3sas/mpt3sas_base.c:5256 _base_allocate_memory_pools()
warn: 'ioc->internal_lookup' double freed

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 7fa3bdb..a6dbc73 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4898,8 +4898,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
 		    ioc->config_page, ioc->config_page_dma);
 	}
 
-	kfree(ioc->hpr_lookup);
-	kfree(ioc->internal_lookup);
+	if (ioc->hpr_lookup) {
+		kfree(ioc->hpr_lookup);
+		ioc->hpr_lookup = NULL;
+	}
+	if (ioc->internal_lookup) {
+		kfree(ioc->internal_lookup);
+		ioc->internal_lookup = NULL;
+	}
 	if (ioc->chain_lookup) {
 		for (i = 0; i < ioc->scsiio_depth; i++) {
 			for (j = ioc->chains_per_prp_buffer;
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] mpt3sas: Fix double free warnings
  2020-05-08  9:18 [PATCH] mpt3sas: Fix double free warnings Suganath Prabu S
@ 2020-05-08 10:42 ` Johannes Thumshirn
  2020-05-08 11:36 ` Dan Carpenter
  1 sibling, 0 replies; 3+ messages in thread
From: Johannes Thumshirn @ 2020-05-08 10:42 UTC (permalink / raw)
  To: Suganath Prabu S, linux-scsi
  Cc: dan.carpenter, Sathya.Prakash, sreekanth.reddy

On 08/05/2020 11:19, Suganath Prabu S wrote:
> -	kfree(ioc->hpr_lookup);
> -	kfree(ioc->internal_lookup);
> +	if (ioc->hpr_lookup) {
> +		kfree(ioc->hpr_lookup);
> +		ioc->hpr_lookup = NULL;
> +	}
> +	if (ioc->internal_lookup) {
> +		kfree(ioc->internal_lookup);
> +		ioc->internal_lookup = NULL;
> +	}

The check before kfree() isn't needed, you could simplify this to:

	kfree(ioc->hpr_lookup);
	ioc->hpr_lookup = NULL;
	kfree(ioc->internal_lookup);
	ioc->internal_lookup = NULL;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] mpt3sas: Fix double free warnings
  2020-05-08  9:18 [PATCH] mpt3sas: Fix double free warnings Suganath Prabu S
  2020-05-08 10:42 ` Johannes Thumshirn
@ 2020-05-08 11:36 ` Dan Carpenter
  1 sibling, 0 replies; 3+ messages in thread
From: Dan Carpenter @ 2020-05-08 11:36 UTC (permalink / raw)
  To: Suganath Prabu S; +Cc: linux-scsi, Sathya.Prakash, sreekanth.reddy

On Fri, May 08, 2020 at 05:18:54AM -0400, Suganath Prabu S wrote:
> Fix below warnings from Smatch static analyser:
> drivers/scsi/mpt3sas/mpt3sas_base.c:5256 _base_allocate_memory_pools()
> warn: 'ioc->hpr_lookup' double freed
> 
> drivers/scsi/mpt3sas/mpt3sas_base.c:5256 _base_allocate_memory_pools()
> warn: 'ioc->internal_lookup' double freed
> 
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
> index 7fa3bdb..a6dbc73 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
> @@ -4898,8 +4898,14 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
>  		    ioc->config_page, ioc->config_page_dma);
>  	}
>  
> -	kfree(ioc->hpr_lookup);
> -	kfree(ioc->internal_lookup);
> +	if (ioc->hpr_lookup) {
> +		kfree(ioc->hpr_lookup);
> +		ioc->hpr_lookup = NULL;
> +	}
> +	if (ioc->internal_lookup) {
> +		kfree(ioc->internal_lookup);
> +		ioc->internal_lookup = NULL;
> +	}


We could remove the if statements because kfree()ing a NULL is a no-op.
I think the build bots will automatically send a patch suggesting to do
that when they see this patch.

Really there is no way that these massive free everything in every
situation functions will ever work 100%.  There is a simple and correct
method to do error handling which is the "Free the most recent
allocation" method.

1) Every function cleans up it's own allocations.
2) Every allocation function has a mirrored free function.
3) Always use clear label names like "goto free_variable_x;"
4) The goto should free the most recent allocation.

The results of rule number 4 are:
1) You never free things which haven't been allocated.
2) The error handling is in the reverse/mirror order from the allocation
3) The error handling is simple because you only need to remember the
   most recent allocation.  Easy to audit.  No leaks.  No bugs.

It looks like this in practice.

int my_func(void)
{
	a = alloc();
	if (!a)
		return -ENOMEM;

	b = alloc();
	if (!b) {
		ret = -ENOMEM:
		goto free_a;
	}

	c = alloc();
	if (!c) {
		ret = -ENOMEM;
		goto free_b;
	}

	return 0;

free_b:
	free(b);
free_a:
	free(a);
	return ret;
}

Then cut and paste and add a free(c); to create the free function.

void my_free_func(void)
{
	free(c);
	free(b);
	free(a);
}

This method removes all the if statements in the error handling path but
it uses more labels so the number of lines is basically the same.  There
is one more rule for unwinding from loops and this code has a lot of
looped allocations:  Release the partial iteration before breaking
from the loop.

	for (i = 0; i < count; i++) {
		array[i].a = alloc();
		if (!array[i].a) {
			ret = -ENOMEM;
			goto unwind;
		}

		array[i].b = alloc();
		if (!array[i].b) {
			free(array[i].a);
			ret = -ENOMEM;
			goto unwind;
		}
	}

	...

unwind:
	while (--i >= 0) {
		free(array[i].b);
		free(array[i].a);
	}

The style here with a big _base_release_memory_pools() function that has
to handle partially allocated resources will never work 100% correctly.
Fortunately the remaining bugs are minor leaks and not crashing bugs so
that's probably as good as we can hope for.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-05-08 11:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-08  9:18 [PATCH] mpt3sas: Fix double free warnings Suganath Prabu S
2020-05-08 10:42 ` Johannes Thumshirn
2020-05-08 11:36 ` Dan Carpenter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.