diff options
author | Xavier Hernandez <jahernan@redhat.com> | 2017-12-15 12:37:06 +0100 |
---|---|---|
committer | Xavier Hernandez <jahernan@redhat.com> | 2017-12-15 12:43:32 +0100 |
commit | 238ebd4db6b399eba221516912cab0726949a3c9 (patch) | |
tree | cdde88cfcb5b76b1aff7f86030c660ce3665834d | |
parent | 62ca4aec69b206723f809ce79bb501fa7bf46249 (diff) |
glusterd: Fix buffer overflow in glusterd_get_volopt_content
The size of the description of each option in gluster has become
greater than the hardcoded maximum size, causing a buffer overflow
when requesting a list of all options.
This patch uses dynamic memory to store all the information.
Change-Id: I115cb9b55fc440434638bf468a50db055cdf271d
BUG: 1526402
Signed-off-by: Xavier Hernandez <jahernan@redhat.com>
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 24d276b7cb0..a0a2a53830a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -13074,9 +13074,9 @@ glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out) int ret = -1; char *def_val = NULL; char *descr = NULL; - char output_string[51200] = {0, }; char *output = NULL; - char tmp_str[2048] = {0, }; + size_t size = 0; + size_t used = 0; #if (HAVE_LIB_XML) xmlTextWriterPtr writer = NULL; xmlBufferPtr buf = NULL; @@ -13088,6 +13088,15 @@ glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out) } #endif + if (!xml_out) { + size = 65536; + output = GF_MALLOC(size, gf_common_mt_char); + if (output == NULL) { + ret = -1; + goto out; + } + } + CDS_INIT_LIST_HEAD (&vol_opt_handle.list); for (vme = &glusterd_volopt_map[0]; vme->key; vme++) { @@ -13140,10 +13149,31 @@ glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out) "Libxml not present"); #endif } else { - snprintf (tmp_str, sizeof (tmp_str), "Option: %s\nDefault " - "Value: %s\nDescription: %s\n\n", - vme->key, def_val, descr); - strcat (output_string, tmp_str); + void *tmp; + int len; + + do { + len = snprintf(output + used, size - used, + "Option: %s\nDefault Value: %s\n" + "Description: %s\n\n", + vme->key, def_val, descr); + if (len < 0) { + ret = -1; + goto cont; + } + if (used + len < size) { + used += len; + break; + } + + size += (len + 65536) & ~65535; + tmp = GF_REALLOC(output, size); + if (tmp == NULL) { + ret = -1; + goto cont; + } + output = tmp; + } while (1); } cont: if (dl_handle) { @@ -13170,24 +13200,25 @@ cont: "Libxml not present"); #endif - if (!xml_out) - output = gf_strdup (output_string); - else + if (xml_out) #if (HAVE_LIB_XML) output = gf_strdup ((char *)buf->content); + if (NULL == output) { + ret = -1; + goto out; + } #else gf_msg ("glusterd", GF_LOG_ERROR, 0, GD_MSG_MODULE_NOT_INSTALLED, "Libxml not present"); #endif - if (NULL == output) { - ret = -1; - goto out; - } - ret = dict_set_dynstr (ctx, "help-str", output); + if (ret >= 0) { + output = NULL; + } out: + GF_FREE(output); gf_msg_debug ("glusterd", 0, "Returning %d", ret); return ret; } |