gdb_server: fix memory leaks in users of get_reg_features_list() 17/1917/6
authorChristian Eggers <ceggers@gmx.de>
Sun, 2 Feb 2014 12:25:16 +0000 (13:25 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Tue, 4 Mar 2014 20:17:53 +0000 (20:17 +0000)
v4:
- changed first line of commit message
v3:
- added extra LOG_ERROR() message
v2:
- Added missing "goto error"
- free also the on extra element of features[]

In contrast to target_get_gdb_reg_list(), the list returned by
get_reg_features_list() consists of items which are itself
malloc'ed.
--> Free the list items prior freeing the list itself.

Additionally:
- gdb_generate_target_description():
  o Do error handling similar as gdb_get_target_description_chunk() does.
- gdb_get_target_description_chunk()
  o **features must be initialised prior an "goto error" can happen

Change-Id: Iad07824618c51084e0aa0499ee6fc96198b320f0
Signed-off-by: Christian Eggers <ceggers@gmx.de>
Reviewed-on: http://openocd.zylin.com/1917
Tested-by: jenkins
Reviewed-by: Trevor Woerner <trevor.woerner@linaro.org>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/server/gdb_server.c

index d4cc2744c63f48839748a84be6b1b40c45cd1008..63c5f6bbd2e86914604dba4a78fcdb4f836a131b 100644 (file)
@@ -2050,8 +2050,10 @@ static int get_reg_features_list(struct target *target, char **feature_list[], i
 static int gdb_generate_target_description(struct target *target, char **tdesc_out)
 {
        int retval = ERROR_OK;
-       struct reg **reg_list;
+       struct reg **reg_list = NULL;
        int reg_list_size;
+       char **features = NULL;
+       int feature_list_size = 0;
        char *tdesc = NULL;
        int pos = 0;
        int size = 0;
@@ -2061,21 +2063,22 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
 
        if (retval != ERROR_OK) {
                LOG_ERROR("get register list failed");
-               return ERROR_FAIL;
+               retval = ERROR_FAIL;
+               goto error;
        }
 
        if (reg_list_size <= 0) {
-               free(reg_list);
-               return ERROR_FAIL;
+               LOG_ERROR("get register list failed");
+               retval = ERROR_FAIL;
+               goto error;
        }
 
-       char **features = NULL;
        /* Get a list of available target registers features */
-       retval = get_reg_features_list(target, &features, NULL, reg_list, reg_list_size);
+       retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size);
        if (retval != ERROR_OK) {
                LOG_ERROR("Can't get the registers feature list");
-               free(reg_list);
-               return ERROR_FAIL;
+               retval = ERROR_FAIL;
+               goto error;
        }
 
        /* If we found some features associated with registers, create sections */
@@ -2155,8 +2158,13 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
        xml_printf(&retval, &tdesc, &pos, &size,
                        "</target>\n");
 
-       free(reg_list);
+error:
+
+       /* note: features[] contains (feature_list_size + 1) elements */
+       for (int j = feature_list_size; j >= 0; j--)
+               free(features[j]);
        free(features);
+       free(reg_list);
 
        if (retval == ERROR_OK)
                *tdesc_out = tdesc;
@@ -2225,6 +2233,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte
        int retval = ERROR_OK;
        struct reg **reg_list = NULL;
        int reg_list_size = 0;
+       char **features = NULL;
        int feature_list_size = 0;
        char **features = NULL;
 
@@ -2236,6 +2245,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte
        }
 
        if (reg_list_size <= 0) {
+               LOG_ERROR("get register list failed");
                retval = ERROR_FAIL;
                goto error;
        }
@@ -2255,11 +2265,13 @@ static int gdb_target_description_supported(struct target *target, int *supporte
        }
 
 error:
-       if (reg_list != NULL)
-               free(reg_list);
 
-       if (features != NULL)
-               free(features);
+       /* note: features[] contains (feature_list_size + 1) elements */
+       for (int j = feature_list_size; j >= 0; j--)
+               free(features[j]);
+       free(features);
+
+       free(reg_list);
 
        return retval;
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)