diff mbox series

[03/11] util/selfmap: Discard mapping on error

Message ID 20210712215535.1471256-4-richard.henderson@linaro.org
State Superseded
Headers show
Series Fixes for clang-13 plus tcg/ppc | expand

Commit Message

Richard Henderson July 12, 2021, 9:55 p.m. UTC
From clang-13:
util/selfmap.c:26:21: error: variable 'errors' set but not used \
    [-Werror,-Wunused-but-set-variable]

Quite right of course, but there's no reason not to check errors.

First, incrementing errors is incorrect, because qemu_strtoul
returns an errno not a count -- just or them together so that
we have a non-zero value at the end.

Second, if we have an error, do not add the struct to the list,
but free it instead.

Cc: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 util/selfmap.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

-- 
2.25.1

Comments

Eric Blake July 13, 2021, 4:06 p.m. UTC | #1
On Mon, Jul 12, 2021 at 02:55:27PM -0700, Richard Henderson wrote:
> From clang-13:

> util/selfmap.c:26:21: error: variable 'errors' set but not used \

>     [-Werror,-Wunused-but-set-variable]

> 

> Quite right of course, but there's no reason not to check errors.

> 

> First, incrementing errors is incorrect, because qemu_strtoul

> returns an errno not a count -- just or them together so that

> we have a non-zero value at the end.

> 

> Second, if we have an error, do not add the struct to the list,

> but free it instead.

> 

> Cc: Alex Bennée <alex.bennee@linaro.org>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  util/selfmap.c | 28 ++++++++++++++++------------

>  1 file changed, 16 insertions(+), 12 deletions(-)


> 

> diff --git a/util/selfmap.c b/util/selfmap.c

> index 2ec99dfdda..0178c2ff8b 100644

> --- a/util/selfmap.c

> +++ b/util/selfmap.c

> @@ -23,29 +23,33 @@ GSList *read_self_maps(void)

>              gchar **fields = g_strsplit(lines[i], " ", 6);

>              if (g_strv_length(fields) > 4) {

>                  MapInfo *e = g_new0(MapInfo, 1);

> -                int errors;

> +                int errors = 0;

>                  const char *end;

>  

> -                errors  = qemu_strtoul(fields[0], &end, 16, &e->start);

> -                errors += qemu_strtoul(end + 1, NULL, 16, &e->end);

> +                errors |= qemu_strtoul(fields[0], &end, 16, &e->start);

> +                errors |= qemu_strtoul(end + 1, NULL, 16, &e->end);

>  

>                  e->is_read  = fields[1][0] == 'r';

>                  e->is_write = fields[1][1] == 'w';

>                  e->is_exec  = fields[1][2] == 'x';

>                  e->is_priv  = fields[1][3] == 'p';

>  

> -                errors += qemu_strtoul(fields[2], NULL, 16, &e->offset);

> +                errors |= qemu_strtoul(fields[2], NULL, 16, &e->offset);

>                  e->dev = g_strdup(fields[3]);


e->dev now contains malloc'd memory...

> -                errors += qemu_strtou64(fields[4], NULL, 10, &e->inode);

> +                errors |= qemu_strtou64(fields[4], NULL, 10, &e->inode);


...and if this qemu_strtou64 fails...

>  

> -                /*

> -                 * The last field may have leading spaces which we

> -                 * need to strip.

> -                 */

> -                if (g_strv_length(fields) == 6) {

> -                    e->path = g_strdup(g_strchug(fields[5]));

> +                if (!errors) {

> +                    /*

> +                     * The last field may have leading spaces which we

> +                     * need to strip.

> +                     */

> +                    if (g_strv_length(fields) == 6) {

> +                        e->path = g_strdup(g_strchug(fields[5]));

> +                    }

> +                    map_info = g_slist_prepend(map_info, e);

> +                } else {

> +                    g_free(e);


...you've now leaked it.  Oops.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org
Richard Henderson July 13, 2021, 5:10 p.m. UTC | #2
On 7/13/21 9:06 AM, Eric Blake wrote:
>>                   e->dev = g_strdup(fields[3]);

> 

> e->dev now contains malloc'd memory...

> 

>> -                errors += qemu_strtou64(fields[4], NULL, 10, &e->inode);

>> +                errors |= qemu_strtou64(fields[4], NULL, 10, &e->inode);

> 

> ...and if this qemu_strtou64 fails...

> 

>>   

>> -                /*

>> -                 * The last field may have leading spaces which we

>> -                 * need to strip.

>> -                 */

>> -                if (g_strv_length(fields) == 6) {

>> -                    e->path = g_strdup(g_strchug(fields[5]));

>> +                if (!errors) {

>> +                    /*

>> +                     * The last field may have leading spaces which we

>> +                     * need to strip.

>> +                     */

>> +                    if (g_strv_length(fields) == 6) {

>> +                        e->path = g_strdup(g_strchug(fields[5]));

>> +                    }

>> +                    map_info = g_slist_prepend(map_info, e);

>> +                } else {

>> +                    g_free(e);

> 

> ...you've now leaked it.  Oops.


Yep, thanks.


r~
diff mbox series

Patch

diff --git a/util/selfmap.c b/util/selfmap.c
index 2ec99dfdda..0178c2ff8b 100644
--- a/util/selfmap.c
+++ b/util/selfmap.c
@@ -23,29 +23,33 @@  GSList *read_self_maps(void)
             gchar **fields = g_strsplit(lines[i], " ", 6);
             if (g_strv_length(fields) > 4) {
                 MapInfo *e = g_new0(MapInfo, 1);
-                int errors;
+                int errors = 0;
                 const char *end;
 
-                errors  = qemu_strtoul(fields[0], &end, 16, &e->start);
-                errors += qemu_strtoul(end + 1, NULL, 16, &e->end);
+                errors |= qemu_strtoul(fields[0], &end, 16, &e->start);
+                errors |= qemu_strtoul(end + 1, NULL, 16, &e->end);
 
                 e->is_read  = fields[1][0] == 'r';
                 e->is_write = fields[1][1] == 'w';
                 e->is_exec  = fields[1][2] == 'x';
                 e->is_priv  = fields[1][3] == 'p';
 
-                errors += qemu_strtoul(fields[2], NULL, 16, &e->offset);
+                errors |= qemu_strtoul(fields[2], NULL, 16, &e->offset);
                 e->dev = g_strdup(fields[3]);
-                errors += qemu_strtou64(fields[4], NULL, 10, &e->inode);
+                errors |= qemu_strtou64(fields[4], NULL, 10, &e->inode);
 
-                /*
-                 * The last field may have leading spaces which we
-                 * need to strip.
-                 */
-                if (g_strv_length(fields) == 6) {
-                    e->path = g_strdup(g_strchug(fields[5]));
+                if (!errors) {
+                    /*
+                     * The last field may have leading spaces which we
+                     * need to strip.
+                     */
+                    if (g_strv_length(fields) == 6) {
+                        e->path = g_strdup(g_strchug(fields[5]));
+                    }
+                    map_info = g_slist_prepend(map_info, e);
+                } else {
+                    g_free(e);
                 }
-                map_info = g_slist_prepend(map_info, e);
             }
 
             g_strfreev(fields);