diff options
| author | Paul Donald | 2025-12-22 23:32:19 +0000 |
|---|---|---|
| committer | Álvaro Fernández Rojas | 2025-12-28 19:41:11 +0000 |
| commit | 6aa4e491a869bcaa60985cf26fc5722a07dd93bb (patch) | |
| tree | f298f4df1a7e3611a2f88627b5b4162f1a266420 | |
| parent | 235cdc97d73b7b6ff559c175278197072cb8820c (diff) | |
| download | odhcp6c-6aa4e491a869bcaa60985cf26fc5722a07dd93bb.tar.gz | |
config: fix potential memory leaks in error paths
In the parsing helpers we do:
`*dst = realloc(*dst, ...); if (!*dst) return -1;`
If a later realloc call failed, the previous buffer
pointer was overwritten with NULL, so the already
allocated block is lost.
We're probably already in a dire situation if we cannot
allocate more memory, so the fix is a principled one.
The caller `config_parse_opt()` does `free(payload)`.
(cherry picked from commit 610e4bddb8d70dd6688e05156428e14c6181ee1a)
Signed-off-by: Paul Donald <newtwen+github@gmail.com>
Link: https://github.com/openwrt/odhcp6c/pull/145
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
| -rw-r--r-- | src/config.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/config.c b/src/config.c index 2866175..4a1b6d9 100644 --- a/src/config.c +++ b/src/config.c @@ -322,9 +322,10 @@ static int config_parse_opt_u8(const char *src, uint8_t **dst) { int len = strlen(src); - *dst = realloc(*dst, len/2); - if (!*dst) + uint8_t *tmp = realloc(*dst, len/2); + if (!tmp) return -1; + *dst = tmp; return script_unhexlify(*dst, len, src); } @@ -345,9 +346,10 @@ static int config_parse_opt_string(const char *src, uint8_t **dst, const bool ar int len = strlen(src); - *dst = realloc(*dst, o_len + len); - if (!*dst) + uint8_t *tmp = realloc(*dst, o_len + len); + if (!tmp) return -1; + *dst = tmp; memcpy(&((*dst)[o_len]), src, len); @@ -381,9 +383,10 @@ static int config_parse_opt_dns_string(const char *src, uint8_t **dst, const boo if (len < 0) return -1; - *dst = realloc(*dst, o_len + len); - if (!*dst) + uint8_t *dst_tmp = realloc(*dst, o_len + len); + if (!dst_tmp) return -1; + *dst = dst_tmp; memcpy(&((*dst)[o_len]), tmp, len); @@ -413,9 +416,10 @@ static int config_parse_opt_ip6(const char *src, uint8_t **dst, const bool array sep++; } - *dst = realloc(*dst, o_len + len); - if (!*dst) + uint8_t *tmp = realloc(*dst, o_len + len); + if (!tmp) return -1; + *dst = tmp; if (inet_pton(AF_INET6, src, &((*dst)[o_len])) < 1) return -1; @@ -445,9 +449,10 @@ static int config_parse_opt_user_class(const char *src, uint8_t **dst, const boo } uint16_t str_len = strlen(src); - *dst = realloc(*dst, o_len + str_len + 2); - if (!*dst) + uint8_t *tmp = realloc(*dst, o_len + str_len + 2); + if (!tmp) return -1; + *dst = tmp; struct user_class { uint16_t len; |