Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 8dad4f3
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
4 changes: 2 additions & 2 deletions auth.c
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion compat.c
Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions http.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions openconnect-internal.h
Expand Up @@ -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 */
Expand Down

0 comments on commit 8dad4f3

Please sign in to comment.