Skip to content
Permalink
Browse files
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: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Feb 18, 2013
1 parent d343108 commit 8dad4f3ad009e45bbd1ba21f1bd03d3f7639deab
Showing with 15 additions and 7 deletions.
  1. +2 −2 auth.c
  2. +1 −1 compat.c
  3. +4 −4 http.c
  4. +8 −0 openconnect-internal.h
4 auth.c
@@ -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;
}
8 http.c
@@ -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 */

0 comments on commit 8dad4f3

Please sign in to comment.