Commit 8dad4f3a authored by David Woodhouse's avatar David Woodhouse

Fix abuse of realloc() causing memory leaks

Implement a helper which actually *does* free the original pointer on
allocation failure, as I evidently always expected it to.

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=700805

Reported by: Niels Thykier <niels@thykier.net>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent d3431088
......@@ -150,8 +150,8 @@ static int parse_auth_choice(struct openconnect_info *vpninfo, struct oc_auth_fo
continue;
opt->nr_choices++;
opt = realloc(opt, sizeof(*opt) +
opt->nr_choices * sizeof(*choice));
realloc_inplace(opt, sizeof(*opt) +
opt->nr_choices * sizeof(*choice));
if (!opt)
return -ENOMEM;
......
......@@ -131,7 +131,7 @@ ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream)
break;
*n *= 2;
*lineptr = realloc(*lineptr, *n);
realloc_inplace(*lineptr, *n);
if (!*lineptr)
return -1;
}
......
......@@ -96,7 +96,7 @@ static void buf_append(struct oc_text_buf *buf, const char *fmt, ...)
break;
}
buf->data = realloc(buf->data, new_buf_len);
realloc_inplace(buf->data, new_buf_len);
if (!buf->data) {
buf->error = -ENOMEM;
break;
......@@ -353,7 +353,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
lastchunk = 1;
goto skip;
}
body = realloc(body, done + chunklen + 1);
realloc_inplace(body, done + chunklen + 1);
if (!body)
return -ENOMEM;
while (chunklen) {
......@@ -394,7 +394,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
/* HTTP 1.0 response. Just eat all we can in 16KiB chunks */
while (1) {
body = realloc(body, done + 16384);
realloc_inplace(body, done + 16384);
if (!body)
return -ENOMEM;
i = openconnect_SSL_read(vpninfo, body + done, 16384);
......@@ -407,7 +407,7 @@ static int process_http_response(struct openconnect_info *vpninfo, int *result,
return i;
} else {
/* Connection closed. Reduce allocation to just what we need */
body = realloc(body, done + 1);
realloc_inplace(body, done + 1);
if (!body)
return -ENOMEM;
break;
......
......@@ -347,6 +347,14 @@ ssize_t openconnect__getline(char **lineptr, size_t *n, FILE *stream);
char *openconnect__strcasestr(const char *haystack, const char *needle);
#endif
/* I always coded as if it worked like this. Now it does. */
#define realloc_inplace(p, size) do { \
void *__realloc_old = p; \
p = realloc(p, size); \
if (size && !p) \
free(__realloc_old); \
} while (0)
/****************************************************************************/
/* tun.c */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment