Re: [PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-16 Thread Miquel Raynal
Hi Richard,

Richard Genoud  wrote on Fri, 16 Oct 2020
14:31:53 +0200:

> Le 15/10/2020 à 18:38, Miquel Raynal a écrit :
> > Hi Richard,  
> 
> >> That's why I prefer only one label and setting NULL.
> >> If I didn't convince you, I'll change it back to multiple labels :)  
> > 
> > You are right it involves less changes when editing the code. But
> > on the other hand it is so often written like [my proposal], that it
> > almost becomes a coding style choice I guess. Anyway, I don't have a
> > strong opinion on this so I'll let you choose the best approach from
> > your point of view, unless you get other comments sharing my thoughts.
> > 
> > Thanks anyway for the cleanup :)
> > 
> > Cheers,
> > Miquèl
> >   
> Hum. You're right, consistency is a good thing.
> I looked around in other files, but I don't think a standard emerges.
> How about I resend the series changing all the remaining functions
> (there's only 3 remaining) to the "NULL/goto out" scheme ?
> 

Sure :)  Maybe you can wait a bit for more feedback before resending
the 18-patch series though.

Cheers,
Miquèl


Re: [PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-16 Thread Richard Genoud

Le 15/10/2020 à 18:38, Miquel Raynal a écrit :

Hi Richard,



That's why I prefer only one label and setting NULL.
If I didn't convince you, I'll change it back to multiple labels :)


You are right it involves less changes when editing the code. But
on the other hand it is so often written like [my proposal], that it
almost becomes a coding style choice I guess. Anyway, I don't have a
strong opinion on this so I'll let you choose the best approach from
your point of view, unless you get other comments sharing my thoughts.

Thanks anyway for the cleanup :)

Cheers,
Miquèl


Hum. You're right, consistency is a good thing.
I looked around in other files, but I don't think a standard emerges.
How about I resend the series changing all the remaining functions
(there's only 3 remaining) to the "NULL/goto out" scheme ?

Regards,
Richard


Re: [PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-15 Thread Miquel Raynal
Hi Richard,

Richard Genoud  wrote on Thu, 15 Oct 2020
18:29:45 +0200:

> Hi Miquel !
> Thanks for your feedback.
> 
> Le 15/10/2020 à 15:54, Miquel Raynal a écrit :
> > Hi Richard,
> > 
> > Richard Genoud  wrote on Wed, 14 Oct 2020
> > 10:06:11 +0200:
> >   
> >> pos_list wasn't freed on every error
> >>
> >> Signed-off-by: Richard Genoud   
> > 
> > Same comment here (and probably after as well) as in patch 05/17, not
> > sure this is actually relevant for the community but I prefer this:
> > 
> > bar = malloc();
> > ...
> > if (ret)
> > goto free_bar;
> > 
> > foo = malloc();
> > ...
> > if (ret)
> > goto free foo;
> > 
> > ...
> > 
> > foo:
> > kfree(foo);
> > bar:
> > kfree(bar);
> > 
> > than:
> > 
> > foo = NULL;
> > bar = NULL;
> > 
> > ...
> > if (ret)
> > goto out;
> > ...
> > if (ret)
> > goto out;
> > ...
> > out:
> > if (ret)
> > kfree(...)  
> 
> I guess it's a coding habit.
> I personnaly prefer the later because I think it's less error-prone :
> When moving code aroung, we don't have to move the labels and rename
> the gotos.
> Ex:
> Let's say we have this code:
>   bar = malloc();
>   ...
>   if (ret)
>   goto free_bar;
> 
>   foo = malloc();
>   ...
>   if (ret)
>   goto free_foo;
>   ret = init_somthing();
>   if (ret)
>   goto free_foo;
>   ret = dummy()
>   if (ret)
>   goto free_foo;
> 
>   ...
> 
>   foo:
>   kfree(foo);
>   bar:
>   kfree(bar);
> 
> And, we want to move, for whatever reason, init_something() and dummy()
> before the foo allocation. We will have to change the code to:
> 
>   bar = malloc();
>   ...
>   if (ret)
>   goto free_bar;
>   ret = init_somthing();
>   if (ret)
>   goto free_bar; // not free_foo anymore !
>   ret = dummy()
>   if (ret)
>   goto free_bar; // ditto
> 
>   foo = malloc();
>   ...
>   if (ret)
>   goto free_foo;
>   ...
> 
>   foo:
>   kfree(foo);
>   bar:
>   kfree(bar);
> 
> Worse, if we have to exchange bar and foo allocation, we'll also have
> to exchange the deallocation of foo and bar and change all gotos beneath :
>   foo = malloc();
>   ...
>   if (ret)
>   goto free_foo;
> 
>   bar = malloc();
>   ...
>   if (ret)
>   goto free_bar;
> 
>   ret = init_somthing();
>   if (ret)
>   goto free_foo; // not free_foo anymore
>   ret = dummy()
>   if (ret)
>   goto free_foo; //ditto
> 
> 
>   ...
> 
> // oops ! we have to exchange that !
>   foo:
>   kfree(foo);
>   bar:
>   kfree(bar);
> 
> 
> That's why I prefer only one label and setting NULL.
> If I didn't convince you, I'll change it back to multiple labels :)

You are right it involves less changes when editing the code. But
on the other hand it is so often written like [my proposal], that it
almost becomes a coding style choice I guess. Anyway, I don't have a
strong opinion on this so I'll let you choose the best approach from
your point of view, unless you get other comments sharing my thoughts.

Thanks anyway for the cleanup :)

Cheers,
Miquèl


Re: [PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-15 Thread Richard Genoud

Hi Miquel !
Thanks for your feedback.

Le 15/10/2020 à 15:54, Miquel Raynal a écrit :

Hi Richard,

Richard Genoud  wrote on Wed, 14 Oct 2020
10:06:11 +0200:


pos_list wasn't freed on every error

Signed-off-by: Richard Genoud 


Same comment here (and probably after as well) as in patch 05/17, not
sure this is actually relevant for the community but I prefer this:

bar = malloc();
...
if (ret)
goto free_bar;

foo = malloc();
...
if (ret)
goto free foo;

...

foo:
kfree(foo);
bar:
kfree(bar);

than:

foo = NULL;
bar = NULL;

...
if (ret)
goto out;
...
if (ret)
goto out;
...
out:
if (ret)
kfree(...)


I guess it's a coding habit.
I personnaly prefer the later because I think it's less error-prone :
When moving code aroung, we don't have to move the labels and rename
the gotos.
Ex:
Let's say we have this code:
bar = malloc();
...
if (ret)
goto free_bar;

foo = malloc();
...
if (ret)
goto free_foo;
ret = init_somthing();
if (ret)
goto free_foo;
ret = dummy()
if (ret)
goto free_foo;

...

foo:
kfree(foo);
bar:
kfree(bar);

And, we want to move, for whatever reason, init_something() and dummy()
before the foo allocation. We will have to change the code to:

bar = malloc();
...
if (ret)
goto free_bar;
ret = init_somthing();
if (ret)
goto free_bar; // not free_foo anymore !
ret = dummy()
if (ret)
goto free_bar; // ditto

foo = malloc();
...
if (ret)
goto free_foo;
...

foo:
kfree(foo);
bar:
kfree(bar);

Worse, if we have to exchange bar and foo allocation, we'll also have
to exchange the deallocation of foo and bar and change all gotos beneath :
foo = malloc();
...
if (ret)
goto free_foo;

bar = malloc();
...
if (ret)
goto free_bar;

ret = init_somthing();
if (ret)
goto free_foo; // not free_foo anymore
ret = dummy()
if (ret)
goto free_foo; //ditto


...

// oops ! we have to exchange that !
foo:
kfree(foo);
bar:
kfree(bar);


That's why I prefer only one label and setting NULL.
If I didn't convince you, I'll change it back to multiple labels :)




---
  fs/squashfs/sqfs.c | 31 +--
  1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 55d183663a8..c4d74fd4d6d 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -722,6 +722,8 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
unsigned long dest_len = 0;
bool compressed;
  
+	*dir_table = NULL;

+   *pos_list = NULL;
/* DIRECTORY TABLE */
table_size = get_unaligned_le64(>fragment_table_start) -
get_unaligned_le64(>directory_table_start);
@@ -736,35 +738,31 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
return -ENOMEM;
  
  	if (sqfs_disk_read(start, n_blks, dtb) < 0)

-   goto free_dtb;
+   goto out;
  
  	/* Parse directory table (metadata block) header */

ret = sqfs_read_metablock(dtb, table_offset, , _len);
if (ret)
-   goto free_dtb;
+   goto out;
  
  	/* Calculate total size to store the whole decompressed table */

metablks_count = sqfs_count_metablks(dtb, table_offset, table_size);
if (metablks_count < 1)
-   goto free_dtb;
+   goto out;
  
  	*dir_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE);

if (!*dir_table)
-   goto free_dtb;
+   goto out;
  
  	*pos_list = malloc(metablks_count * sizeof(u32));

-   if (!*pos_list) {
-   free(*dir_table);
-   goto free_dtb;
-   }
+   if (!*pos_list)
+   goto out;
  
  	ret = sqfs_get_metablk_pos(*pos_list, dtb, table_offset,

   metablks_count);
if (ret) {
metablks_count = -1;
-   free(*dir_table);
-   free(*pos_list);
-   goto free_dtb;
+   goto out;
}
  
  	src_table = dtb + table_offset + SQFS_HEADER_SIZE;

@@ -780,8 +778,7 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
  

Re: [PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-15 Thread Miquel Raynal
Hi Richard,

Richard Genoud  wrote on Wed, 14 Oct 2020
10:06:11 +0200:

> pos_list wasn't freed on every error
> 
> Signed-off-by: Richard Genoud 

Same comment here (and probably after as well) as in patch 05/17, not
sure this is actually relevant for the community but I prefer this:

bar = malloc();
...
if (ret)
goto free_bar;

foo = malloc();
...
if (ret)
goto free foo;

...

foo:
kfree(foo);
bar:
kfree(bar);

than:

foo = NULL;
bar = NULL;

...
if (ret)
goto out;
...
if (ret)
goto out;
...
out:
if (ret)
kfree(...)



> ---
>  fs/squashfs/sqfs.c | 31 +--
>  1 file changed, 17 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
> index 55d183663a8..c4d74fd4d6d 100644
> --- a/fs/squashfs/sqfs.c
> +++ b/fs/squashfs/sqfs.c
> @@ -722,6 +722,8 @@ static int sqfs_read_directory_table(unsigned char 
> **dir_table, u32 **pos_list)
>   unsigned long dest_len = 0;
>   bool compressed;
>  
> + *dir_table = NULL;
> + *pos_list = NULL;
>   /* DIRECTORY TABLE */
>   table_size = get_unaligned_le64(>fragment_table_start) -
>   get_unaligned_le64(>directory_table_start);
> @@ -736,35 +738,31 @@ static int sqfs_read_directory_table(unsigned char 
> **dir_table, u32 **pos_list)
>   return -ENOMEM;
>  
>   if (sqfs_disk_read(start, n_blks, dtb) < 0)
> - goto free_dtb;
> + goto out;
>  
>   /* Parse directory table (metadata block) header */
>   ret = sqfs_read_metablock(dtb, table_offset, , _len);
>   if (ret)
> - goto free_dtb;
> + goto out;
>  
>   /* Calculate total size to store the whole decompressed table */
>   metablks_count = sqfs_count_metablks(dtb, table_offset, table_size);
>   if (metablks_count < 1)
> - goto free_dtb;
> + goto out;
>  
>   *dir_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE);
>   if (!*dir_table)
> - goto free_dtb;
> + goto out;
>  
>   *pos_list = malloc(metablks_count * sizeof(u32));
> - if (!*pos_list) {
> - free(*dir_table);
> - goto free_dtb;
> - }
> + if (!*pos_list)
> + goto out;
>  
>   ret = sqfs_get_metablk_pos(*pos_list, dtb, table_offset,
>  metablks_count);
>   if (ret) {
>   metablks_count = -1;
> - free(*dir_table);
> - free(*pos_list);
> - goto free_dtb;
> + goto out;
>   }
>  
>   src_table = dtb + table_offset + SQFS_HEADER_SIZE;
> @@ -780,8 +778,7 @@ static int sqfs_read_directory_table(unsigned char 
> **dir_table, u32 **pos_list)
> _len, src_table, src_len);
>   if (ret) {
>   metablks_count = -1;
> - free(*dir_table);
> - goto free_dtb;
> + goto out;
>   }
>  
>   if (dest_len < SQFS_METADATA_BLOCK_SIZE) {
> @@ -803,7 +800,13 @@ static int sqfs_read_directory_table(unsigned char 
> **dir_table, u32 **pos_list)
>   src_table += src_len + SQFS_HEADER_SIZE;
>   }
>  
> -free_dtb:
> +out:
> + if (metablks_count < 1) {
> + free(*dir_table);
> + free(*pos_list);
> + *dir_table = NULL;
> + *pos_list = NULL;
> + }
>   free(dtb);
>  
>   return metablks_count;

Thanks,
Miquèl


[PATCH 06/17] fs/squashfs: sqfs_read_directory_table: fix memory leak

2020-10-14 Thread Richard Genoud
pos_list wasn't freed on every error

Signed-off-by: Richard Genoud 
---
 fs/squashfs/sqfs.c | 31 +--
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 55d183663a8..c4d74fd4d6d 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -722,6 +722,8 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
unsigned long dest_len = 0;
bool compressed;
 
+   *dir_table = NULL;
+   *pos_list = NULL;
/* DIRECTORY TABLE */
table_size = get_unaligned_le64(>fragment_table_start) -
get_unaligned_le64(>directory_table_start);
@@ -736,35 +738,31 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
return -ENOMEM;
 
if (sqfs_disk_read(start, n_blks, dtb) < 0)
-   goto free_dtb;
+   goto out;
 
/* Parse directory table (metadata block) header */
ret = sqfs_read_metablock(dtb, table_offset, , _len);
if (ret)
-   goto free_dtb;
+   goto out;
 
/* Calculate total size to store the whole decompressed table */
metablks_count = sqfs_count_metablks(dtb, table_offset, table_size);
if (metablks_count < 1)
-   goto free_dtb;
+   goto out;
 
*dir_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE);
if (!*dir_table)
-   goto free_dtb;
+   goto out;
 
*pos_list = malloc(metablks_count * sizeof(u32));
-   if (!*pos_list) {
-   free(*dir_table);
-   goto free_dtb;
-   }
+   if (!*pos_list)
+   goto out;
 
ret = sqfs_get_metablk_pos(*pos_list, dtb, table_offset,
   metablks_count);
if (ret) {
metablks_count = -1;
-   free(*dir_table);
-   free(*pos_list);
-   goto free_dtb;
+   goto out;
}
 
src_table = dtb + table_offset + SQFS_HEADER_SIZE;
@@ -780,8 +778,7 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
  _len, src_table, src_len);
if (ret) {
metablks_count = -1;
-   free(*dir_table);
-   goto free_dtb;
+   goto out;
}
 
if (dest_len < SQFS_METADATA_BLOCK_SIZE) {
@@ -803,7 +800,13 @@ static int sqfs_read_directory_table(unsigned char 
**dir_table, u32 **pos_list)
src_table += src_len + SQFS_HEADER_SIZE;
}
 
-free_dtb:
+out:
+   if (metablks_count < 1) {
+   free(*dir_table);
+   free(*pos_list);
+   *dir_table = NULL;
+   *pos_list = NULL;
+   }
free(dtb);
 
return metablks_count;